export type MyTuple = ["test", "othertest"];
type NotWorking = {
[K in keyof MyTuple]: { value: MyTuple[K]};
};
type NotWorkingLengthType = NotWorking["length"]; // { value: 2 }
type Working<T>= {
[P in keyof T]: { value: T[P] };
};
type MappedWorking = Working<MyTuple>;
type MappedWorkingLengthType = MappedWorking["length"]; // 2
Run Code Online (Sandbox Code Playgroud)
为什么在这种情况下它的行为有所不同?这让我很困惑。
这实际上看起来像一个错误,请参阅microsoft/TypeScript#27995。
一般形式的映射类型{[K in keyof T]: ...T[K]...}被认为是同态T映射类型,并尽可能保留输入类型的结构。这种情况发生在可选和readonly键上(请参阅microsoft/TypeScript#12563 ),这也是在microsoft/TypeScript#26063中实现映射元组/数组时的意图。
为了使其发挥作用,这意味着编译器必须在评估后查看[K in keyof T]并记住保留. 当是泛型类型时会发生这种情况,对于可选/键,当是某种具体类型时也会发生这种情况:Tkeyof TTreadonlyT
type MyObj = { a?: string, readonly b: number };
type MyMappedObj = { [K in keyof MyObj]: { value: MyObj[K] } }
/* type MyMappedObj = {
a?: {
value: string | undefined;
} | undefined;
readonly b: {
value: number;
};
} */
Run Code Online (Sandbox Code Playgroud)
请注意,这仅当您的映射类型显式迭代具有精确“ in keyof”的键时才有效。如果您以其他方式计算键,或者将它们分配给类型别名,甚至只是将表达式括起来keyof,则该咒语将被破坏并且映射的类型不再是同态的:
type MyBadMappedObj = { [K in (keyof MyObj)]: { value: MyObj[K] } }
/* type MyMappedObj = {
a: { // not optional
value: string | undefined;
}
b: { // not readonly
value: number;
};
} */
Run Code Online (Sandbox Code Playgroud)
因此,映射像这样的键应该保留输出中{[K in keyof T]: ...}的结构。T
不幸的是,当引入映射数组/元组功能时,看起来这只是针对T泛型类型参数实现的,而不是针对特定的具体类型。在此评论中,实施者说:
这里的问题是,当我们实例化元组或数组的通用同态映射类型时,我们仅映射到元组和数组类型(请参见#26063)。我们或许也应该对具有
keyof TwhereT是非泛型类型的同态映射类型执行此操作。
目前情况就是这样。也许这个问题最终会得到解决。在那之前,您可能应该使用像您的示例这样的中间泛型类型Working作为解决方法。
| 归档时间: |
|
| 查看次数: |
1469 次 |
| 最近记录: |