如何让TypeScript泛型中type属性依赖于name属性的值?
如何让TypeScript中type属性的取值依赖于name属性的值?
你当前的代码无法实现预期约束,核心问题在于Attribute<T>的type字段是基于T[keyof T]的联合类型做判断的。T[keyof T]对于Item来说是string | number,TypeScript会将T[keyof T] extends string ? 'a' : 'b'解析为联合类型'a' | 'b',导致不管name选哪个键,type都能随意选'a'或'b'。
要实现name和type的对应约束,需要为每个键单独生成匹配的类型,再组合成联合类型。修改后的类型定义如下:
type Attribute<T> = { [K in keyof T]: { name: K; type: T[K] extends string ? 'a' : 'b'; }; }[keyof T]; type Item = { id: string; date: number; }; const att1: Attribute<Item> = { name: 'id', type: 'a', // 合法,符合预期 }; const att2: Attribute<Item> = { name: 'id', type: 'b', // 类型错误:'"b"'不能赋值给类型'"a"' }; const att3: Attribute<Item> = { name: 'date', type: 'b', // 合法,符合预期 };
代码说明:
[K in keyof T]遍历T的每个键K,为每个键生成专属的对象类型:name固定为当前键K,type根据T[K]的类型动态确定(字符串类型对应'a',数字类型对应'b')。[keyof T]通过索引访问,把映射生成的所有对象类型提取出来组成联合类型。此时Attribute<Item>等价于{name: 'id', type: 'a'} | {name: 'date', type: 'b'},TypeScript会基于联合类型的成员做精确校验,确保name和type的取值严格对应。
内容的提问来源于stack exchange,提问作者MartinP
相关产品推荐
相关产品推荐

