为什么res1
不能像res2
那样知道它的类型是number
?
interface P {
name: string;
age: number;
}
const people: P = {
age: 30,
name: 'Peter',
};
type T = keyof P
type Fn1 = (p: P, t: T) => P[T]
type Fn2 = <P, T extends keyof P>(p: P, t: T) => P[T]
const fn1: Fn1 = (p, t) => {
return p[t]
}
const fn2: Fn2 = (p, t) => {
return p[t]
}
const res1 = fn1(people, 'age');
const res2 = fn2(people, 'age');
最佳答案
首先让我们更改 fn2
的定义所以我们可以理解类型参数的重要性。我们不会将自己与 T
混淆。这是 keyof P
.
type Fn2 = <P, Tx extends keyof P>(p: P, t: Tx) => P[Tx]
函数的通用版本始终将通用类型参数作为现有函数的额外参数,以帮助编译器解析类型。 fn1
没有类型参数,在这种情况下编译器无法区分 fn1(people, 'age') and fn1(people, 'name')
.
在编译时扩展 fn1,
(p: P, key: "age" | "name") => p['age' | 'name']
编译器没有可用的通用参数来存储传递的 key 。类型参数就像变量,编译器可以存储在进一步编译中有用的信息。
但是对于 fn2,fn2(people, 'age')
的类型参数如下,
<P, 'age'>(p: P, 'age': 'age' | 'name') => p['age']
,这里Tx
因为通用参数是编译器在编译时知道的“年龄”,它可以将此信息与帮助编译器解析的函数一起存储 p['age'] as
数`。
关于typescript - 为什么 TypeScript 中的 keyof word 在 2 `type defination` 秒内表现不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58908691/