泛型:将类型用作打字稿中的对象键

时间:2019-09-16 11:36:49

标签: typescript visual-studio-code typescript-generics

使用包含通过管道|在一起的字符串的类型时,这意味着这些字符串中的任何一个都可以用作值。在下面的示例中,TFoo包含这三个值foobarbaz

使用[P in TFoo],我们可以告诉打字稿,那些字符串中的任何一个都可以用作类型TDirect的对象中的键。 VSCode可帮助完成代码,我们可以成功构建direct,没有错误。

在我们的情况下,TFoo并不总是相同,实际上,取决于微服务,它将包含不同的事件名称。因此,我们尝试使用TGeneric中的泛型。这就是T下划线的地方,我们得到以下错误:

Type 'T' is not assignable to type 'string | number | symbol'.
  Type 'T' is not assignable to type 'symbol'.ts(2322)

尽管奇怪的是,VSCode似乎了解我们正在尝试做的事情,但它仍然有助于智能感知并正确地将wrong: "value"突出显示为不正确。

tsc将导致编译器错误(请参见上文)。当在自己的文件中移动TGeneric以及使用例如ts-node --files src(假设所有文件都保存在src中)一切正常。

因此,由于智能感知,并且代码仍在ts-node上运行,因此我们目前遇到的问题是无法获得所需的东西。但是我们实际上对这种奇怪的行为有一种不好的感觉。

也许有人有防弹解决方案?

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


type TDirect = { [P in TFoo]?: any };
const direct: TDirect = {
  bar: "baz"
}


type TGeneric<T> = { [P in T]?: any };
const generic: TGeneric<TFoo> = {
  bar: "baz",
  wrong: "value"
}

1 个答案:

答案 0 :(得分:0)

我相信这是因为索引签名中的密钥类型必须是字符串或数字。因此,您必须将T限制为string | number

type TGeneric<T extends string | number> = { [P in T]?: any };

请参阅:https://www.typescriptlang.org/play/index.html#code/C4TwDgpgBAKgYgewVAvFARAMyeqAfDAIwEMAnXA9EgL3QCg7RJYBxCAOwlIEsBjAHhhQIAD2AcAJgGcoU4D3YBzfFHYBXALaEuAPlRQA3lADaABSjd2sALoB+AFxRi7EFAC+Abga8E7OVEUOLj5HGDZOHgF4JD00AzooKBJSRypiWgAaBKgAd1JfRVSAN2IAGzUIejcgA