You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 22:52:52