如何让泛型类型中的对象属性相互依赖?
解决TypeScript中属性依赖的类型约束问题
你当前的代码无法实现value类型跟随key/name类型约束的核心原因是:带默认泛型的TestType/PayloadType在不指定泛型参数时,会被TypeScript解析为所有键值对的联合类型集合,而非单个精确的键值对映射。此时value的类型会变成所有对应值的联合(比如string | number),自然无法限制为当前key对应的具体类型。
方案1:生成精确的联合类型
通过映射类型生成所有合法键值对的联合类型,让TypeScript能识别每个具体的键值组合:
简化示例修复:
type TypeA = { some: 'some2'; thing: 'thing2'; }; // 遍历TypeA的所有键,生成对应的键值对类型,再提取为联合类型 type TestType = { [K in keyof TypeA]: { name: K; value: TypeA[K]; }; }[keyof TypeA]; const test1: TestType = { name: 'some', value: 'some2', // 合法 }; const test2: TestType = { name: 'some', value: 'thing2', // 类型错误:'"thing2"'不能赋值给'"some2"' };
实际需求示例修复:
type StateType = { thingA: string; thingB: number; }; const state: StateType = { thingA: 'somestring', thingB: 10, }; // 生成所有合法的key-value组合联合类型 type PayloadType = { [K in keyof StateType]: { key: K; value: StateType[K]; }; }[keyof StateType]; const setThing = (payload: PayloadType) => { state[payload.key] = payload.value; }; setThing({ key: 'thingA', value: true, // 类型错误:'boolean'不能赋值给'string' }); setThing({ key: 'thingB', value: 'asdas', // 类型错误:'string'不能赋值给'number' });
方案2:使用泛型函数自动推断类型
更灵活的方式是将函数定义为泛型函数,让TypeScript在调用时自动推断当前的键类型,进而约束value的类型:
type StateType = { thingA: string; thingB: number; }; const state: StateType = { thingA: 'somestring', thingB: 10, }; // 泛型K约束为StateType的键,payload的value类型自动关联K对应的类型 const setThing = <K extends keyof StateType>(payload: { key: K; value: StateType[K] }) => { state[payload.key] = payload.value; }; setThing({ key: 'thingA', value: true, // 类型错误 }); setThing({ key: 'thingB', value: 'asdas', // 类型错误 });
这种写法不需要预定义PayloadType,TypeScript会在每次调用setThing时,根据传入的key自动推断K的类型,从而严格约束value的类型。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

