如何定义TS数组类型确保包含枚举所有成员,实现类似Record的校验效果
解决方案
以下是完整可直接运行的实现代码,缺省枚举成员时TS会直接抛出包含缺失项名称的类型错误:
enum TypeEnum { "A" = "A", "B" = "B", } // 数组元素基础类型 type ArrayItem = { type: TypeEnum } // 枚举全覆盖校验工具类型 type AllEnumCovered<T extends ArrayItem[]> = Exclude<TypeEnum, T[number]['type']> extends never ? T : `校验失败:缺失枚举成员 "${Exclude<TypeEnum, T[number]['type']>}"` // 辅助工厂函数,自动推导数组类型并触发校验 function defineResultArray<T extends ArrayItem[]>(arr: AllEnumCovered<T>) { return arr } // 错误示例:缺失枚举成员B,TS直接抛出类型错误提示缺失内容 // const ResultArray = defineResultArray([ // { type: TypeEnum.A } // ]) // 正确示例:包含所有枚举成员,无报错 const ResultArray = defineResultArray([ { type: TypeEnum.A }, { type: TypeEnum.B } ])
实现原理
- 用
Exclude<TypeEnum, T[number]['type']>计算枚举中未在数组type字段中出现的成员集合 - 如果计算结果为
never说明所有枚举值已覆盖,直接返回传入的数组类型 - 如果存在未覆盖的枚举值,返回字面量字符串类型的错误提示,TS会直接将该字符串作为类型错误展示
- 工厂函数无需手动传入泛型参数,TS会自动根据传入的数组内容推导类型并触发校验,使用成本更低
如果不想用工厂函数,也可以手动指定泛型实现校验:
const ResultArray: AllEnumCovered<[{type: TypeEnum.A}, {type: TypeEnum.B}]> = [ {type: TypeEnum.A}, {type: TypeEnum.B} ]
内容的提问来源于stack exchange,提问作者QC CAI
相关产品推荐
相关产品推荐

