首页 > 解决方案 > 是否可以从 Typescript 字符串联合创建对象?

问题描述

我有一个字符串联合类型,比如

type example = "foo" | "bar" | "baz";

是否可以将该类型转换为如下所示的对象?

const example = {
  foo: "foo",
  bar: "bar",
  baz: "baz"
};

我想尽量让它保持干燥,而不必用硬编码的这些值创建一个单独的对象。

标签: typescript

解决方案


我不认为您是否可以使用类型定义创建对象,因为所有内容都被编译为没有强类型信息的 JavaScript。如果你想基于联合创建另一个类型对象,你可以这样做:

type example = "foo" | "bar" | "baz";
type exampleObject = {[key in example]: string}
// equivalent to
// type exampleObject = {
//     foo: string;
//     bar: string;
//     baz: string;
// }

// You can use the object type
const example: exampleObject = {
  foo: "foo",
  bar: "bar",
  baz: "baz"
};

TS Playground 链接:https ://tsplay.dev/w6BOrw

但正如评论所说,如果您想限制示例中给出的值,您可以这样做:

type exampleObjectExact = {[key in example]: key}
// equivalent to
// type exampleObjectExact = {
//     foo: "foo";
//     bar: "bar";
//     baz: "baz";
// }

您还可以使用内置实用程序类型Record

type Result = Record<example, example>;

看到您自己的答案,您似乎稍微更改了问题定义。最初的问题是关于联合类型到对象类型的转换。我假设您对联合类型没有任何控制权,也许它来自图书馆或其他东西。但是,如果您对此有控制权,则可以这样做(@Aleksey 正确地提到了这一点):

const example = ['foo', 'bar', 'baz'] as const;

type exampleObjExact = { [key in typeof example[number]]: key }
// is equivalent to
// type exampleObjExact = {
//     foo: "foo";
//     bar: "bar";
//     baz: "baz";
// }

const x = example.reduce<exampleObjExact>((cum, v) => ({...cum, v}), {} as any)

TS 游乐场:https ://tsplay.dev/WPjreN


推荐阅读