如何在TypeScript中基于key隐式约束InnerType的name属性可选值?
问题:基于
key隐式约束name的可选值 需求是让OuterType中的x和y字段无需显式指定泛型,同时保证每个对象的key与name属性类型严格对应——比如key为"A"时,name只能是1|2|3;key为"B"时,name只能是4|5|6。
正确解决方案
通过联合类型实现InnerType,将TypeMap中每个key对应的结构合并成联合,TypeScript会自动推断key与name的对应关系:
type TypeMap = { A: 1 | 2 | 3; B: 4 | 5 | 6; }; // 生成包含所有合法key-name组合的联合类型 type InnerType = { [K in keyof TypeMap]: { key: K; name: TypeMap[K]; // 其他属性可在此添加 }; }[keyof TypeMap]; type OuterType = { x: InnerType; y: InnerType; }; // 合法示例 const foo: OuterType = { x: { key: "A", name: 2 }, y: { key: "B", name: 4 }, }; // 以下代码会触发类型错误(符合预期) // const invalidFoo: OuterType = { // x: { key: "A", name: 4 }, // 4不属于TypeMap["A"]的可选值 // };
现有方案的问题分析
Partial包裹对象的方案
该方案用Partial<{ [key in keyof TypeMap]: TypeMap[key] }>定义data字段,无法保证单一key的约束——既允许空对象,也允许同时传入多个key对应的value,完全不符合原需求中{key, name}的结构要求。无关联的key和name方案
此方案将key设为keyof TypeMap,name设为所有TypeMap值的联合类型,无法建立key与name的对应关系,会出现key: "A"却传入name: 4的非法情况,达不到类型安全的目的。
内容的提问来源于stack exchange,提问作者nick zoum
相关产品推荐
相关产品推荐

