无法理解 TypeScript 中 keyof 的语义
Unable to understand the semantics of keyof in TypeScript
我有下面的简单示例,其中声明了 K extends keyof T
,但是为 findMember
推断的 return 类型的结果是不同的,我真的不明白为什么会有差别这么大
我还创建了一个 link 到 TypeScript Playground HERE
class Group1<T> {
findMember<K extends keyof T = keyof T>(name: K): T[K] {
return {} as T[K];
}
}
class Group2<T, K extends keyof T = keyof T> {
findMember(name: K): T[K] {
return {} as T[K];
}
}
interface Person {
firstName: string;
lastName: string;
age: number;
addresses: Array<{
street: string;
city: string;
zip: string;
}>
}
const group1 = new Group1<Person>();
// Inferred type is Array<{ street: string; city: string; zip: string; }>;
const addresses1 = group1.findMember('addresses');
const group2 = new Group2<Person>();
// Inferred type is string | number | Array<{ street: string; city: string; zip: string; }>;
const addresses2 = group2.findMember('addresses');
在group1.findMember('addresses')
中,K
可以推断为"addresses"
,所以Person["addresses"]
是returned.
在 group2.findMember('addresses')
中,K
是来自顶级 class 声明的类型参数。
使用其默认类型 keyof T
(T
的所有键),因为您在使用 const group2 = new Group2<Person>();
创建实例时没有指定 K
。所以你最终得到 return 类型 Person["firstName" | "lastName" | "age" | "addresses"]
,它是所有可能的 属性 值的并集。
如果您使用 const group2 = new Group2<Person, "addresses">()
,结果应该相同。
我有下面的简单示例,其中声明了 K extends keyof T
,但是为 findMember
推断的 return 类型的结果是不同的,我真的不明白为什么会有差别这么大
我还创建了一个 link 到 TypeScript Playground HERE
class Group1<T> {
findMember<K extends keyof T = keyof T>(name: K): T[K] {
return {} as T[K];
}
}
class Group2<T, K extends keyof T = keyof T> {
findMember(name: K): T[K] {
return {} as T[K];
}
}
interface Person {
firstName: string;
lastName: string;
age: number;
addresses: Array<{
street: string;
city: string;
zip: string;
}>
}
const group1 = new Group1<Person>();
// Inferred type is Array<{ street: string; city: string; zip: string; }>;
const addresses1 = group1.findMember('addresses');
const group2 = new Group2<Person>();
// Inferred type is string | number | Array<{ street: string; city: string; zip: string; }>;
const addresses2 = group2.findMember('addresses');
在group1.findMember('addresses')
中,K
可以推断为"addresses"
,所以Person["addresses"]
是returned.
在 group2.findMember('addresses')
中,K
是来自顶级 class 声明的类型参数。
使用其默认类型 keyof T
(T
的所有键),因为您在使用 const group2 = new Group2<Person>();
创建实例时没有指定 K
。所以你最终得到 return 类型 Person["firstName" | "lastName" | "age" | "addresses"]
,它是所有可能的 属性 值的并集。
如果您使用 const group2 = new Group2<Person, "addresses">()
,结果应该相同。