ts泛型函数的参数传递类型和泛型函数的内部定义类型有什么区别吗?
我知道 keyof 可以为对象类型生成其键的字符串或数字文字联合
类型数据 = { 一个:字符串, b:数量 } keyof Data;//'a' | 'b'
但是如果我将它应用于文字类型,我将得到与其所有属性相似的联合类型type Test = keyof 'a';
// result
type Test = number | typeof Symbol.iterator | "toString" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | ... 30 more ... | "padEnd"
我知道 typescript 中的“in”运算符可用于遍历目标类型的属性名称
type Test = {
[P in keyof 'a']: '??'
};
type T = Test;
// result
type T = {
[x: number]: "??";
toString: "??";
charAt: "??";
charCodeAt: "??";
concat: "??";
indexOf: "??";
lastIndexOf: "??";
localeCompare: "??";
match: "??";
replace: "??";
search: "??";
slice: "??";
split: "??";
... 30 more ...;
[Symbol.iterator]: "??";
}
但是我不明白为什么一旦通过泛型传入结果就完全不同了
type Test<V> = {
[P in keyof V]: '??'
};
type T = Test<'a'>;
// result
type T = 'a'
最佳答案
这与mapped type是否有关。有问题的被编译器视为同态(有关 TypeScript 中“同态”含义的更多详细信息,请参阅 What does "homomorphic mapped type" mean?)。答案在 this comment on microsoft/TypeScript#41575 中给出(稍微转述):
The key issue here is that
{ [P in keyof T]: '??' }
, whereT
is a naked type variable, is considered a homomorphic mapped type, whereas{ [P in keyof 'a']: '??' }
is not becausekeyof 'a'
is eagerly resolved to a union of literal types. For homomorphic mapped types
if T is a union type we distribute the mapped type over the union,
if T is a primitive type no mapping is performed and the result is simply T,
if T is an array we map to an array where the element type has been transformed,
if T is a tuple we map to a tuple where the element types have been transformed, and
otherwise we map to an object type where the type of each property has been transformed.
We've had these distinctions in place for a very long time, not sure we can change it now without breaking lots of code.
所以在 { [P in keyof 'a']: '??' }
编译器急切地将 keyof 'a'
计算为 union的literal types例如 "toString"| “charAt”
(以及 index signature 的 number
和相关 symbol
键),然后尽职地映射此联合。
但是在 { [P in keyof T]: '??' }
其中 T
是通用的,编译器将整个事物视为同态映射类型,而像 "a"
这样的原语上的同态映射类型只是评估它们的值直接输入,即"a"
。编译器在任何时候都不会尝试在这里计算keyof "a"
。
关于typescript - 泛型函数参数传递内部是否做了任何处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74718012/