如何定义各字段用独立泛型的TypeScript索引签名并模拟对应行为?
TypeScript 动态键值类型约束实现方案
基础场景:键类型与值类型一致
你想要实现的「每个类型为K的键对应值类型也为K」的约束,TypeScript 可以通过泛型索引类型结合自引用约束来实现:
首先定义一个辅助类型,它要求对象的每个属性值类型严格等于其键的类型:
type KeyEqualsValue<T> = { [K in keyof T]: K; };
使用时,将变量的类型指定为该辅助类型对变量自身类型的推导结果,TypeScript 会自动校验每个键值对是否符合规则:
// 符合规则,编译通过 const validRecord: KeyEqualsValue<typeof validRecord> = { 2: 2, "string": "string", "there is": "there is" }; // 不符合规则,编译报错(值5的类型与键2的类型不匹配) const invalidRecord: KeyEqualsValue<typeof invalidRecord> = { 2: 5, };
复杂场景:值类型为 Something<V[K]>
针对你实际场景中值类型为 Something<V[K]> 的需求,我们可以基于索引类型来定义约束:
假设 Something 是你的泛型包装类型,比如:
type Something<T> = { content: T };
我们定义 ComplexCase<V> 类型,要求对象的键必须是 V 的键(keyof V),且每个键 K 对应的值类型必须是 Something<V[K]>:
// 可选键版本:允许只包含V的部分键 type ComplexCase<V> = { [K in keyof V]?: Something<V[K]>; }; // 必填键版本:必须包含V的所有键 // type ComplexCase<V> = { // [K in keyof V]: Something<V[K]>; // };
示例使用:
// 定义V类型,指定键与对应的值基础类型 type V = { id: number; name: string; desc: boolean; }; // 符合规则,编译通过 const validComplex: ComplexCase<V> = { id: { content: 1001 }, name: { content: "TypeScript" } }; // 不符合规则,编译报错(desc对应的值类型应为Something<boolean>) const invalidComplex: ComplexCase<V> = { desc: { content: "not a boolean" } };
这种方式完全模拟了你设想的无效语法的约束逻辑,同时符合 TypeScript 的类型系统规范。
内容的提问来源于stack exchange,提问作者Fudge Fudge
相关产品推荐
相关产品推荐

