如何创建仅排除完全匹配类型而非子类型的TypeScript StrictExclude工具类型?
实现方案
你可以直接基于StrictExtract的逻辑反向推导实现,只需要把双extends匹配成功时的返回值从T换成never即可:
type StrictExclude<T, U> = T extends unknown ? U extends T ? T extends U ? never : T : T : T;
如果需要适配更复杂的联合类型判断场景,也可以搭配通用的类型全等判断工具实现,逻辑更稳妥:
// 通用类型全等判断工具 type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends (<T>() => T extends Y ? 1 : 2) ? true : false type StrictExclude<T, U> = T extends unknown ? Equal<T, Extract<U, T>> extends true ? never : T : never
验证效果
用你提供的示例测试,完全符合预期:
type objOne = { prop1: string; prop2: number; } type objTwo = { prop1: string; prop2: number; prop3: Function; } // 原生Exclude结果为never type excl = Exclude<objOne | objTwo | string | number, objOne | string | number> // StrictExclude结果为 objTwo type strExcl = StrictExclude<objOne | objTwo | string | number, objOne | string | number>
实现逻辑
- 首先用
T extends unknown触发分布式条件类型,遍历T的每一个联合成员 - 对每一个
T的成员,判断它是否和U中的某一个成员完全相等 - 如果完全相等就返回
never排除该类型,否则返回原类型保留
内容的提问来源于stack exchange,提问作者james
相关产品推荐
相关产品推荐

