TypeScript基于Enum定义至少含1个枚举键的接口实现问题
解决方案
你可以通过通用工具类型实现「二选一必居其一」的约束,完整实现如下:
export enum EId { userId = 'userId', customerId = 'customerId', } // 通用工具类型:要求传入的类型中任意一个属性必填,其余可选 type RequireOnlyOne<T, Keys extends keyof T = keyof T> = Keys extends keyof T ? Partial<Omit<T, Keys>> & Required<Pick<T, Keys>> : never; // 基于枚举定义ID字段基础类型 type IIdBase = { [key in EId]: string } // 生成满足二选一要求的ID参数类型 export type IIdParam = RequireOnlyOne<IIdBase> // 合并paramString字段得到最终可用类型 export type IIdParamString = IIdParam & { paramString: string }
效果验证
符合要求的写法都会正常通过类型校验:
// 仅含userId const params1: IIdParamString = { userId: '1234', paramString: 'limit' } // 仅含customerId const params2: IIdParamString = { customerId: '5678', paramString: 'limit' } // 同时传两个ID也支持,符合「无需同时存在」的非互斥要求 const params3: IIdParamString = { userId: '1234', customerId: '5678', paramString: 'limit' }
不符合要求的写法会触发类型报错:
// 两个ID都缺省,直接报错 const params4: IIdParamString = { paramString: 'limit' }
可选扩展
如果你需要强制两个ID互斥,不能同时存在,可以替换为如下工具类型:
type RequireOnlyOneExclusive<T, Keys extends keyof T = keyof T> = Keys extends keyof T ? Omit<T, Keys> & Required<Pick<T, Keys>> & Partial<Record<Exclude<keyof T, Keys>, never>> : never;
替换后同时传两个ID会直接触发类型错误,按需选择即可。
内容的提问来源于stack exchange,提问作者Ehrlich_Bachman
相关产品推荐
相关产品推荐

