TypeScript如何声明负类型?自定义ExclusionType工具类实现
TypeScript 负类型模拟及 ExclusionType 工具类实现
负类型的实现思路
TypeScript 没有原生的"负类型"(直接声明"非某类型")语法,但可以借助条件类型和 never 类型来模拟这种排除特定类型的效果。
实现 ExclusionType 工具类
要写出能排除指定类型 T 的 ExclusionType,核心是从顶层类型 unknown 中剔除 T 的所有子类型,直接上代码:
// 基础版:适用于大多数基础类型场景 type ExclusionType<T> = Exclude<unknown, T>; // 增强版:处理 never、unknown、any 等特殊边界情况 type ExclusionType<T> = T extends never ? never : unknown extends T ? never : any extends T ? never : Exclude<unknown, T>;
验证效果
const a1: ExclusionType<string> = 123; // ✅ 合法,数字不属于 string 类型 const a2: ExclusionType<string> = "abc"; // ❌ 报错,字符串属于被排除的类型 const a3: ExclusionType<number> = "hello"; // ✅ 合法 const a4: ExclusionType<boolean> = null; // ✅ 合法(null 不是布尔值)
逻辑说明
unknown是 TypeScript 的顶层类型,包含所有可能的类型,Exclude<unknown, T>就是从所有类型里去掉T及其子类型,正好满足"非 T 类型"的需求。- 增强版里的条件判断是为了处理特殊情况:比如如果
T是unknown,"非 unknown 类型"不存在,所以返回never;如果T是any,同样逻辑返回never;never本身是空类型,也特殊处理返回never。
和函数参数排除逻辑的区别
你之前用的函数参数排除方式:
type ParameterExclusionString = <T>(arg: T extends string ? never : T) => any; const test_fn: ParameterExclusionString = (arg) => {}; test_fn(123); // ✅ 允许 test_fn("abc"); // ❌ 不允许
这是通过泛型条件约束来限制函数参数,而 ExclusionType 是直接定义一个类型,用于约束变量的赋值类型。两者核心都是利用条件类型和 never 来排除特定类型,但应用场景不同:前者针对函数入参,后者针对变量类型声明。
内容的提问来源于stack exchange,提问作者Autumn
相关产品推荐
相关产品推荐

