TypeScript嵌套keyof类型推断异常:无法实现深度3类型钻取
解决TypeScript嵌套keyof类型钻取的类型推断问题
问题原因
你遇到的Type '"c"' cannot be used to index type 'Base[KBase][KA]'错误,本质是TypeScript在泛型定义阶段无法确定Base[KBase][KA]类型一定包含'c'这个键。虽然当前代码中Base[KBase]是A类型,其键'b'对应的值是包含'c'的B类型,但泛型约束仅限制了KA是Base[KBase]的键,并没有保证该键对应的值类型存在'c'索引。如果未来A类型新增其他键(比如x: number),KA可以是'x',此时Base[KBase][KA]是number,自然没有'c'键,TypeScript会提前报错规避这种风险。
解决方案
方案1:针对性约束泛型参数
如果只需要适配当前固定的类型结构,可以直接约束KA为特定的键,确保其对应的值类型包含'c':
type Base = { a: A; }; type A = { b: B; }; type B = { c: C; }; type C = { d: string; }; // 约束KA必须是Base[KBase]中值类型包含'c'的键 type DrillDown3<KBase extends keyof Base, KA extends keyof Base[KBase] & { [P in keyof Base[KBase]]: 'c' extends keyof Base[KBase][P] ? P : never }[keyof Base[KBase]]> = Base[KBase][KA]['c']; // 使用示例:正常推断为C类型 type TestDrillDown3 = DrillDown3<'a', 'b'>;
这种方式通过条件类型筛选出符合要求的键,既保留了泛型的灵活性,又避免了类型错误。
方案2:通用任意深度钻取类型
如果需要支持任意深度的类型钻取,推荐实现一个递归的路径解析类型,适配更复杂的业务场景:
type Base = { a: A; }; type A = { b: B; }; type B = { c: C; }; type C = { d: string; }; // 递归生成所有可能的路径(数组形式) type Path<T> = T extends object ? { [K in keyof T]: [K] | [K, ...Path<T[K]>]; }[keyof T] : []; // 根据路径获取对应类型 type Get<T, P extends any[]> = P extends [infer K, ...infer Rest] ? K extends keyof T ? Get<T[K], Rest> : never : T; // 使用示例:支持任意深度钻取 type DrillDown1 = Get<Base, ['a', 'b']>; // B类型 type DrillDown2 = Get<Base, ['a', 'b', 'c']>; // C类型 type DrillDown3 = Get<Base, ['a', 'b', 'c', 'd']>; // string类型
这个方案无需为每个深度单独定义类型,只要传入对应的路径数组,就能自动推断出目标类型,扩展性极强。
内容的提问来源于stack exchange,提问作者jmm9
相关产品推荐
相关产品推荐

