TypeScript:如何通过函数第一个参数缩小第二个参数的类型?
解决TypeScript中基于第一个参数缩小第二个参数类型范围的问题
问题描述
你希望实现一个函数:传入第一个参数(父对象的键)后,第二个参数(对应子对象的键)能获得精确的代码补全提示,但原函数定义会报错,无法达到预期效果。
解决方案
使用泛型约束关联两个参数的类型,让TypeScript能根据第一个参数的具体值,自动推断出第二个参数的合法类型:
const obj = { parent1: { child1: "child-key1", child2: "child-key2", }, parent2: { child3: "child-key3", child4: "child-key4", } } as const // 用泛型约束第一个参数的具体键类型 const func = <ParentKey extends keyof typeof obj>( parentKeyName: ParentKey, // 基于泛型获取对应子对象的键类型 childKeyName: keyof typeof obj[ParentKey] ) => {} // 调用示例:输入第一个参数后,第二个参数会自动提示对应子键 func("parent2", "child3") // 合法,补全正常 func("parent1", "child2") // 合法 // func("parent1", "child3") // 非法,触发类型错误,符合预期
原写法报错原因
原函数中,parentKeyName的类型是keyof typeof obj,即联合类型"parent1" | "parent2"。此时typeof obj[parentKeyName]会被推断为两个子对象的联合类型:
{ child1: "child-key1"; child2: "child-key2"; } | { child3: "child-key3"; child4: "child-key4"; }
而keyof作用于联合类型时,只会返回所有成员共有的键。由于这两个子对象没有共同键,最终keyof typeof obj[parentKeyName]的结果是never,导致第二个参数的类型无效,从而报错。
泛型的作用是将parentKeyName的类型从联合类型缩小为具体的单个键类型,当你传入具体的父键时,TypeScript会自动推断出ParentKey的具体值,进而精确计算出对应子对象的键类型,既解决了报错问题,又实现了代码补全的需求。
内容的提问来源于stack exchange,提问作者Pekehata
相关产品推荐
相关产品推荐

