typescript - 泛型函数参数传递内部是否做了任何处理?

标签 typescript typescript-generics

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]: "??";
}

image

但是我不明白为什么一旦通过泛型传入结果就完全不同了

type Test<V> = {
    [P in keyof V]: '??'
};
type T = Test<'a'>;
// result
type T = 'a'

image

最佳答案

这与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]: '??' }, where T is a naked type variable, is considered a homomorphic mapped type, whereas { [P in keyof 'a']: '??' } is not because keyof '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' 计算为 unionliteral types例如 "toString"| “charAt”(以及 index signaturenumber 和相关 symbol 键),然后尽职地映射此联合。

但是在 { [P in keyof T]: '??' } 其中 T 是通用的,编译器将整个事物视为同态映射类型,而像 "a" 这样的原语上的同态映射类型只是评估它们的值直接输入,即"a"。编译器在任何时候都不会尝试在这里计算keyof "a"

关于typescript - 泛型函数参数传递内部是否做了任何处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74718012/

相关文章:

TypeScript 泛型 "extends"约束 : Is there a nullable constraint?

typescript - 如果已知数组类型,则保留数组类型

TypeScript 映射类型值取决于键

typescript - 如何输入以接口(interface)作为参数的方法

TypeScript 条件通用接口(interface)作为参数(数组或对象,基于 bool 值)

javascript - 无法将值绑定(bind)到 setter 中 p-autocomplete 中的 ngModel

html - 模式背景元素的正确 HTML 角色和其他相关属性 (TypeScript React)

typescript - Webpack DefinePlugin 不替换输出中的文本

javascript - 在VS 2012中查看typescript输出的js文件

使用解构的剩余参数进行 Typescript 函数重载类型推断