如何声明TypeScript的DerivedType,使其与UnionType成员同步校验?
解决方案
当然可以实现这个需求,以下是几种符合要求的TypeScript类型声明方式,既能让DerivedType与UnionType保持同步,又能为每个属性指定特定类型:
方法一:交叉类型强制覆盖所有联合成员
通过交叉Record<UnionType, unknown>来确保DerivedType包含UnionType的所有属性,同时保留自定义的属性类型:
type UnionType = 'prop1' | 'prop2' | 'prop3'; type DerivedType = { prop1: string; prop2: number; prop3: boolean; } & Record<UnionType, unknown>;
当你给UnionType添加新成员(比如'prop4'),TypeScript会立即报错,提示DerivedType缺少对应的属性prop4,因为交叉类型要求同时满足两个结构的约束。
方法二:辅助类型显式检查缺失成员
定义一个辅助类型,专门验证目标类型是否覆盖了联合类型的所有成员,错误提示更直观:
// 辅助类型:如果T包含U的所有键则返回T,否则返回never type EnsureAllUnionMembers<T, U extends keyof any> = Exclude<U, keyof T> extends never ? T : never; type UnionType = 'prop1' | 'prop2' | 'prop3'; type DerivedType = EnsureAllUnionMembers<{ prop1: string; prop2: number; prop3: boolean; }, UnionType>;
若DerivedType遗漏了UnionType中的某个成员,Exclude<U, keyof T>会返回缺失的键,此时EnsureAllUnionMembers会返回never,TypeScript会抛出类型不兼容的错误。
方法三:映射类型适配keyof场景(适合你的实际需求)
如果你的UnionType是来自另一个类型的keyof,可以结合映射类型和类型映射表来实现:
// 原始类型,UnionType由它的keyof生成 type OriginalType = { prop1: any; prop2: any; prop3: any; }; type UnionType = keyof OriginalType; // 定义每个属性的具体配置类型 type PropConfigMap = { prop1: string; prop2: number; prop3: boolean; }; // 强制DerivedType包含所有UnionType成员,并使用PropConfigMap的对应类型 type DerivedType = { [K in UnionType]: PropConfigMap[K]; };
当OriginalType添加新属性时,UnionType会自动更新,此时DerivedType的映射类型会要求PropConfigMap添加对应属性的类型,否则会抛出类型“K”无法用于索引类型“PropConfigMap”的错误。
以上三种方法都避免了使用Record<UnionType, any>,同时能确保两个类型保持同步,满足你为每个属性指定特定类型的需求。
内容的提问来源于stack exchange,提问作者TrueWill
相关产品推荐
相关产品推荐

