TypeScript如何创建提取对象匹配指定类型的属性键的泛型类型
问题原因
你的实现出现不符合预期的结果,根源是TypeScript的分布式条件类型特性:当条件判断左侧是未被包装的裸泛型参数时,如果传入的参数是联合类型,TypeScript会自动把联合类型的每个成员单独代入条件判断,最后把所有分支的结果合并成新的联合类型。
你传入U = string | number时,判断逻辑会被拆分为两个独立分支:
string extends T[K] ? T[K] extends string ? K : never : nevernumber extends T[K] ? T[K] extends number ? K : never : never
对于I['a'] = string类型,第一个分支判断为真返回'a',第二个分支判断为假返回never,合并后'a'会被保留,同理'd'也会被保留,最终结果和预期不符。
修正方案
只需要把条件判断的两侧用方括号包裹,阻止分布式条件类型触发,让联合类型作为整体参与判断即可:
type KeyOfType<T, U> = NonNullable<{ [K in keyof T]: [U] extends [T[K]] ? [T[K]] extends [U] ? K : never : never; }[keyof T]>;
效果验证
interface I { a: string; b: number|string; c: string|number; d: string; } type T1 = KeyOfType<I, string>; // 'a'|'d' 符合预期 type T2 = KeyOfType<I, string|number>; // 'b'|'c' 符合预期 type T3 = KeyOfType<I, number>; // never 符合预期
内容的提问来源于stack exchange,提问作者Larry
相关产品推荐
相关产品推荐

