如何根据TypeScript中兄弟属性的值推断目标属性类型
解决TypeScript中兄弟属性的类型关联推断问题
你的问题核心是要让name和value的类型严格关联:当name属于Extended的键时,value只能是对应类型的键数组;当name不属于Extended时,禁止传入value。之前的泛型写法失效是因为默认泛型参数为联合类型,导致value的类型变成了所有可能情况的混合,无法和name的具体值绑定。
正确的类型定义方案
我们可以通过映射类型生成区分联合类型来实现需求,让每个name的取值对应唯一合法的value类型:
type Base = { key1: string; key2: string; key3: string; } type Extended = { key1: { prop1: string; prop2: string }; key2: { prop1: string }; } // 生成关联name和value的联合类型 type Test = { [K in keyof Base]: K extends keyof Extended ? { name: K; value?: (keyof Extended[K])[] } : { name: K; value?: never } }[keyof Base]
代码解释
- 映射类型遍历所有键:遍历
Base的所有键K,为每个键生成对应的对象类型 - 条件分支处理两种情况:
- 如果
K是Extended的键,生成包含name: K和可选value的对象,value类型为Extended[K]的键组成的数组 - 如果
K不是Extended的键,生成包含name: K和value?: never的对象,never类型的属性无法赋值任何有效值,相当于禁止传入value
- 如果
- 转换为联合类型:通过
[keyof Base]取出映射类型的所有值,组成最终的联合类型,TypeScript会自动根据name的值推断value的合法类型
测试验证
// 合法:name为key1,value是对应类型的键数组 const test1: Test = { name: 'key1', value: ['prop1', 'prop2'] } // 合法:name为key1,可以省略value const test1NoValue: Test = { name: 'key1' } // 合法:name为key2,value只能是prop1相关数组 const test2: Test = { name: 'key2', value: ['prop1'] } // 非法:key2的value不能包含prop2(会报错) // const test2Invalid: Test = { // name: 'key2', // value: ['prop2'] // } // 合法:name为key3,不能传入value const test3: Test = { name: 'key3' } // 非法:key3传入value会报错 // const test3Invalid: Test = { // name: 'key3', // value: [] // }
这种写法的优势是自动维护:如果Base或Extended的键发生变化,Test类型会自动更新,无需手动修改。
内容的提问来源于stack exchange,提问作者Echo
相关产品推荐
相关产品推荐

