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

TypeScript中NonNullable<T>定义解析及相关语法疑问咨询

关于TypeScript中NonNullable、Exclude、Extract类型的解释

首先回答你第一个问题:TypeScript没有内置的Nullable<T>类型,但你可以很容易自己定义一个,用来表示允许T、null或undefined的类型:

type Nullable<T> = T | null | undefined;

接下来逐个解释你找到的这些内置工具类型:

1. NonNullable

定义:

/**
 * Exclude null and undefined from T
 */
type NonNullable<T> = T extends null | undefined ? never : T;

这是TypeScript内置的工具类型,核心作用是从类型T中彻底排除null和undefined。

关键语法解析:

  • 条件类型(T extends U ? X : Y):这是TypeScript的条件类型语法,逻辑和JavaScript三元运算符类似——判断T是否可以赋值给U,满足条件返回X,不满足则返回Y。
  • never关键字:这是TypeScript的底层特殊类型,代表「永远不会存在的类型」。当never与其他类型组成联合类型时,会被自动忽略(比如string | never等价于string)。所以当T是null或undefined时,这个类型返回never,最终就把这两个类型从结果中剔除了。

举个实际例子:

type Example = NonNullable<string | null | undefined>;
// Example 的最终类型是 string

2. Exclude<T, U>

定义:

/**
 * Exclude from T those types that are assignable to U
 */
type Exclude<T, U> = T extends U ? never : T;

作用是从类型T中排除所有能赋值给U的类型成员。

它利用了条件类型的分布式特性:当T是联合类型时,TypeScript会自动把联合类型的每个成员单独代入条件判断,再把结果重新组合成新的联合类型。

举个例子:

type Example = Exclude<string | number | boolean, number | boolean>;
// Example 的最终类型是 string

拆解执行逻辑:

  • string extends number | boolean ? never : string → 返回string
  • number extends number | boolean ? never : number → 返回never
  • boolean extends number | boolean ? never : boolean → 返回never
    最终联合结果:string | never | never → 简化为string

3. Extract<T, U>

定义:

/**
 * Extract from T those types that are assignable to U
 */
type Extract<T, U> = T extends U ? T : never;

和Exclude正好相反,作用是从类型T中提取所有能赋值给U的类型成员。

同样依赖分布式条件类型的特性:
举个例子:

type Example = Extract<string | number | boolean, number | boolean>;
// Example 的最终类型是 number | boolean

拆解执行逻辑:

  • string extends number | boolean ? string : never → 返回never
  • number extends number | boolean ? number : never → 返回number
  • boolean extends number | boolean ? boolean : never → 返回boolean
    最终联合结果:never | number | boolean → 简化为number | boolean

关于你提到的泛型约束场景中的?和never

  • never的含义:除了在工具类型中用来排除类型,never还可以表示函数永远不会返回(比如抛出错误、无限循环的函数),或者表示不可能存在的类型分支。在泛型约束中,如果某个类型参数被约束为never,意味着这个类型参数没有合法的取值。
  • ?运算符:你可能混淆了两个场景的?:
    1. 可选属性中的?:比如interface User { name?: string },这里的?表示该属性是可选的,对应的类型等价于string | undefined。
    2. 条件类型中的?:这是条件类型语法的一部分(T extends U ? X : Y),不属于独立运算符,只是用来分隔条件判断和结果分支的语法标记。

内容的提问来源于stack exchange,提问作者zsoumya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:02:21