TypeScript如何声明泛型容器数组,无需枚举所有泛型参数?
解决方案
可以通过分布式条件类型自动生成所有Container泛型实例的联合,无需手动枚举Types的取值,后续如果Types新增枚举值也能自动同步,无需修改定义。
原写法
Container<Types>[]校验失效的原因是TS会把泛型参数的联合直接展开到属性上,允许p和q分别取联合中的不同值;而分布式条件类型会把每个联合分支单独处理成独立的Container实例,再组合成联合,就可以保证每个元素内部p和q的类型一致。
第一步:定义自动分发的工具类型
type Types = 'a' | 'b' interface Container<T extends Types> { p: T, q: T, } // 分布式条件类型:会自动遍历Types的所有联合分支生成对应的Container实例,最终组合为联合类型 type DistributeContainer<T> = T extends Types ? Container<T> : never // 等价于 Container<'a'> | Container<'b'>,无需手动枚举 type ValidContainer = DistributeContainer<Types>
第二步:使用生成的类型定义数组
const arr: ValidContainer[] = [ { p: 'a', q: 'a', }, { p: 'b', q: 'a', // 编译器会正常抛出类型错误,校验生效 }, ];
可选简化方案(泛型推导工具函数)
如果不想显式声明数组类型,可以封装工具函数利用TS自动推导能力完成校验,写法更简洁:
const createContainerArr = <T extends Types>(arr: DistributeContainer<T>[]) => arr // 无需手动写类型注解,自动完成校验 const arr = createContainerArr([ { p: 'a', q: 'a', }, { p: 'b', q: 'a', // 自动触发类型错误 }, ])
内容的提问来源于stack exchange,提问作者Alex Chen
相关产品推荐
相关产品推荐

