如何在TypeScript中实现支持属性为原值或对应数组的泛型Partial类型
TypeScript 泛型工具类型实现方案
核心功能实现
你需要的泛型工具可以通过映射类型直接实现,能严格保证属性值和原类型的对应关系,不会出现允许传入不匹配类型值的问题:
type PartialWithArray<T extends object> = { [K in keyof T]?: T[K] | T[K][] }
使用示例
针对你给出的DataModel接口,使用效果如下:
interface DataModel { type: string; count: number; } // 生成的目标类型 type FilteredData = PartialWithArray<DataModel> // 实际类型等价于: // { // type?: string | string[]; // count?: number | number[]; // } // 校验通过 const case1: FilteredData = { type: 'foo'} const case2: FilteredData = { type: ['foo', 'bar'] } // 类型报错:number 不能赋值给 string | string[] const case3: FilteredData = { type: 1 }
原实现问题说明
你之前基于Record的实现逻辑本身是成立的,但需要额外处理泛型U的约束,使用映射类型直接遍历原对象的键可以更稳妥地绑定属性和对应类型,避免出现类型漏校验的问题,同时也不需要额外定义KeyOf工具类型。
可选增强:仅允许原始类型属性
如果需要限制只能传入原始类型的属性,非原始类型属性直接报错,可以使用如下增强版本:
// 定义原始类型集合 type Primitive = string | number | boolean | null | undefined | symbol type PartialWithArrayOnlyPrimitive<T extends object> = { [K in keyof T]: T[K] extends Primitive ? T[K] | T[K][] : never }
如果原接口存在非原始类型的属性,该属性会被标记为never类型,赋值时会直接触发类型错误。
内容的提问来源于stack exchange,提问作者Poul Kruijt
相关产品推荐
相关产品推荐

