泛型:在打字稿中使用类型作为对象键

Generics: use type as object key in typescript

当使用包含管道 | 的字符串的类型时,这意味着这些字符串中的任何一个都可以用作值。在下面的示例中,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" 不正确。

A 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"
}

我认为这是因为索引签名中的键类型必须是字符串或数字。因此你必须限制 Tstring | number:

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

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