Typescript中如何为泛型对象定义类型安全的键值对数组类型
解决方案
你最初的写法存在的问题是,key和value的类型是两个独立的联合类型,没有建立绑定关系:keyof Person 是 'name' | 'age',T[keyof T] 是 string | number,所以TypeScript不会校验两者的对应关系,自然不会对错误的value类型报错。
正确的类型定义
你可以通过遍历泛型参数的所有键,构造每个键对应的绑定类型,再取联合类型的方式实现需求:
type KeyValArr<T> = { [K in keyof T]: { key: K; value: T[K]; } }[keyof T][]
类型验证
用你给出的Person类型测试:
type Person = { name: string; age: number; } // 符合预期的写法,无报错 const myPersonKV: KeyValArr<Person> = [ { key: 'name', value: 'john' }, { key: 'age', value: 22 } ] // 错误写法会触发类型报错:key为'age'时value必须为number类型 const tmp: KeyValArr<Person> = [ { key: 'age', value: 'wrong type!' } ]
原理解释
- 首先用映射类型
[K in keyof T]遍历T的所有键,为每个键K单独构造对应的键值对类型{key: K, value: T[K]},此时每个键和对应值的类型是强绑定的 - 用
[keyof T]取映射类型的所有值的联合,得到所有合法键值对对象的联合类型 - 最后添加
[]将联合类型包装为数组,就得到了类型安全的键值对数组类型
内容的提问来源于stack exchange,提问作者Amin_mmz
相关产品推荐
相关产品推荐

