泛型:在打字稿中使用类型作为对象键
Generics: use type as object key in typescript
当使用包含管道 |
的字符串的类型时,这意味着这些字符串中的任何一个都可以用作值。在下面的示例中,TFoo
包含这三个值,foo
、bar
和 baz
.
使用 [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"
}
我认为这是因为索引签名中的键类型必须是字符串或数字。因此你必须限制 T
到 string | number
:
type TGeneric<T extends string | number> = { [P in T]?: any };
当使用包含管道 |
的字符串的类型时,这意味着这些字符串中的任何一个都可以用作值。在下面的示例中,TFoo
包含这三个值,foo
、bar
和 baz
.
使用 [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"
}
我认为这是因为索引签名中的键类型必须是字符串或数字。因此你必须限制 T
到 string | number
:
type TGeneric<T extends string | number> = { [P in T]?: any };