- 文档
- 教程
【免费下载链接】typescript-book
The Concise TypeScript Book: A Concise Guide to Effective Development in TypeScript. Free and Open Source.
本文基于开源书籍《The Concise TypeScript Book》第 40 章 Tipi condizionali(条件类型) 展开,系统讲解 TypeScript 条件类型的定义语法、extends检查与三元分支的求值机制,并结合本书后续章节覆盖可分配条件类型(Distributive Conditional Types)、infer类型推断以及内置预定义条件类型。读完本文,你可以掌握如何用条件类型编写「类型取决于条件结果」的可复用类型工具,并理解其在类型体操与工具类型设计中的典型应用。
条件类型是什么
条件类型(Conditional Types)是一种「根据条件动态决定最终类型」的类型构造方式:待创建的类型由条件的求值结果决定。它由关键字extends与三元运算符组合而成,在类型层面实现「如果……那么……否则……」的二选一分支。
书中的原始示例(见 conditional-types.md)如下:
type IsArray<T> = T extends any[] ? true : false; const myArray = [1, 2, 3]; const myNumber = 42; type IsMyArrayAnArray = IsArray<typeof myArray>; // Type true type IsMyNumberAnArray = IsArray<typeof myNumber>; // Type false这个示例完整展示了条件类型的三个组成部分:
- 被检查的类型(check type):
T,即类型参数传入的待判定类型; - 约束检查(extends 子句):
T extends any[]表示「T是否可赋值给任意数组类型」; - 三元分支:条件成立时取
true,否则取false。
IsArray<typeof myArray>的求值结果是字面量类型true,而IsArray<typeof myNumber>的求值结果是false。注意条件类型在编译期类型系统内求值,与运行时的if语句无关——它操作的对象是类型本身,因此常用于编写类型守卫工具、类型谓词式的判定逻辑。
语义要点:extends 是「可赋值性」检查
T extends U ? A : B中extends的含义是「T是否可赋值于U」,与继承语义的extends不同:
IsArray<number[]>中number[]可赋值给any[],结果为true;IsArray<number>中number不可赋值给any[],结果为false;- 若把条件改为
T extends number[] ? "num" : "other",则number[]命中"num",而string[]命中"other",可以据此写出更精细的类型级判定函数。
可分配条件类型:对联合类型逐成员分发
本书第 41 章 Tipi condizionali distributivi(可分配条件类型) 进一步介绍了条件类型的一个关键特性:当检查的类型参数是裸(naked)类型参数且传入值为联合类型时,条件类型会对联合的每个成员分别求值,再把结果合并为新的联合。这一特性在处理映射类型(mapped types)与高阶类型时尤其有用。
书中原示例:
type Nullable<T> = T extends any ? T | null : never; type NumberOrBool = number | boolean; type NullableNumberOrBool = Nullable<NumberOrBool>; // number | boolean | null拆解Nullable<number | boolean>的求值过程:
- 对
number求值:number extends any成立,得到number | null; - 对
boolean求值:boolean extends any成立,得到boolean | null; - 两次结果合并:
(number | null) | (boolean | null),化简后即为number | boolean | null。
需要注意的分发前提是「裸类型参数」:只有被检查的类型参数直接出现在extends左侧时才会触发分发;若将其包裹(例如T[] extends any[]中的T[]),联合类型将作为整体参与判定,不再逐成员分发。
infer 关键字:在条件类型中抽取子类型
第 42 章 infer 关键字(条件类型中的类型推断) 说明了infer的用法:在条件类型的extends子句内部声明一个待推断的类型变量,当条件成立时,TypeScript 会反向「提取」出匹配该模式的子类型。这让类型定义更灵活、更可复用。
书中原示例:
type ElementType<T> = T extends (infer U)[] ? U : never; type Numbers = ElementType<number[]>; // number type Strings = ElementType<string[]>; // stringElementType<number[]>的求值逻辑是:number[]匹配(infer U)[]这一模式,于是U被推断为number,条件成立,返回U,即number。若传入的不是数组(例如ElementType<number>),则落到never分支。infer还能匹配函数签名、元组等更复杂结构,是手写ReturnType等工具类型的基础手段。
预定义条件类型:语言内置的常用转换
第 43 章 Tipi Condizionali Predefiniti(预定义条件类型) 列出了 TypeScript 语言内置提供的一批工具类型,它们针对给定类型的常见特征执行类型转换。书中列出的内置工具类型及其语义如下:
| 工具类型 | 作用 |
|---|---|
Exclude<UnionType, ExcludedType> | 从联合类型中移除所有可赋值给ExcludedType的成员 |
Extract<Type, Union> | 从联合类型中保留所有可赋值给Type的成员 |
NonNullable<Type> | 移除类型中的null与undefined |
ReturnType<Type> | 提取函数类型Type的返回类型 |
Parameters<Type> | 提取函数类型Type的参数类型 |
Required<Type> | 将Type的所有属性变为必填 |
Partial<Type> | 将Type的所有属性变为可选 |
Readonly<Type> | 将Type的所有属性变为只读 |
其中Exclude、Extract、NonNullable、ReturnType、Parameters本质上是基于条件类型(及infer)构建的;而Partial、Required、Readonly在实现上属于映射类型(mapped types),书中将其一并归入「内置类型工具」的范畴讲解。了解这些内置类型等于掌握了一组「条件类型 + 映射类型」的组合范式,自造同类工具类型时可直接参照其结构。
小结与延伸阅读
条件类型把「类型判定 + 类型转换」统一到一套T extends U ? A : B的语法中:基础形态用extends与三元分支表达条件;裸类型参数对联合类型自动分发,实现逐成员转换;infer让条件类型具备子类型抽取能力;而Exclude、Extract、ReturnType等内置工具类型则是这些机制在生产级类型库中的标准体现。
本书中与此主题直接相关的章节(意大利语版):
- 第 40 章 条件类型
- 第 41 章 可分配条件类型
- 第 42 章 infer 关键字(条件类型中的类型推断)
- 第 43 章 预定义条件类型
- 第 40 章 英文原文
以上示例均为纯类型级代码,可直接复制到任意启用了strict模式的 TypeScript 项目中验证其求值结果。
- 文档
- 教程
【免费下载链接】typescript-book
The Concise TypeScript Book: A Concise Guide to Effective Development in TypeScript. Free and Open Source.
相关推荐
条件类型(Conditional Types)深度指南:基于 The Concise TypeScript Book 的 extends 三元逻辑、infer 提取与内置工具类型全解析
条件类型(Conditional Types)深度指南:基于 The Concise TypeScript Book 的 extends 三元逻辑、infer
文档教程The Concise TypeScript Book:深入理解预定义条件类型(Predefined Conditional Types)
The Concise TypeScript Book:深入理解预定义条件类型(Predefined Conditional Types) 预定义条件类型(Pr
文档教程The Concise TypeScript Book:预定义条件类型(Predefined Conditional Types)深入解析
The Concise TypeScript Book:预定义条件类型(Predefined Conditional Types)深入解析 TypeScript
文档教程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考