如何限制TypeScript的keyof仅接受值类型为指定类型的键?
实现TypeScript泛型键筛选:仅保留值类型匹配指定类型的键
要实现仅筛选出对象类型T中值类型为F的键,我们可以通过条件映射类型改造Key泛型类型,具体实现如下:
interface Data { items: string[]; name: string; } // 改造后的Key类型:仅保留T中值类型属于F的键 type Key<T, F> = { [K in keyof T]: T[K] extends F ? K : never; }[keyof T] & string; interface TextField<T> { input: 'text'; // 限定key对应T中的值为string类型 key: Key<T, string>; } interface ArrayField<T> { input: 'array'; // 限定key对应T中的值为数组类型(用unknown[]适配任意数组) key: Key<T, unknown[]>; } type Field<T> = TextField<T> | ArrayField<T>; // ✅ 正确示例:无报错,key类型与input类型匹配 const validConfig: Field<Data>[] = [ { input: 'text', key: 'name' // name对应string类型,符合TextField要求 }, { input: 'array', key: 'items' // items对应string[]类型,符合ArrayField要求 } ]; // ❌ 错误示例:触发类型报错,key与input类型不匹配 const invalidConfig: Field<Data>[] = [ { input: 'text', key: 'items' // items是数组类型,不符合TextField的string要求 }, { input: 'array', key: 'name' // name是string类型,不符合ArrayField的数组要求 } ];
核心逻辑说明
Key泛型的实现:
- 通过映射类型
{ [K in keyof T]: ... }遍历T的所有键 - 对每个键
K,用条件类型T[K] extends F ? K : never判断值类型是否匹配F:匹配则保留键名K,否则设为never - 最后通过
[keyof T]索引访问,提取所有非never的键,得到符合条件的键的联合类型,再与string交叉确保结果仅为字符串键
- 通过映射类型
TextField与ArrayField的约束:
TextField<T>指定Key<T, string>,确保key对应的T属性值是string类型ArrayField<T>指定Key<T, unknown[]>,适配任意数组类型(如果需要严格限定数组元素类型,可以替换为string[]等具体类型)
内容的提问来源于stack exchange,提问作者Ewan
相关产品推荐
相关产品推荐

