尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

The Concise TypeScript Book 解读:Type Manipulation(类型操作)完全指南——从类型创建类型到内置工具类型

发布时间:2026/9/28 3:10:21

资讯中心
01
ARTICLE

The Concise TypeScript Book 解读:Type Manipulation(类型操作)完全指南——从类型创建类型到内置工具类型

The Concise TypeScript Book 解读:Type Manipulation(类型操作)完全指南——从类型创建类型到内置工具类型
文档教程【免费下载链接】typescript-bookThe Concise TypeScript Book: A Concise Guide to Effective Development in TypeScript. Free and Open Source.项目地址https://gitcode.com/gh_mirrors/typ/typescript-book点击查看免费下载本篇指南源自开源仓库 typescript-bookThe Concise TypeScript Book葡萄牙语版文档 type-manipulation.md是全书第 61 章的完整展开。读完本文你将掌握如何通过交集、联合、映射、条件等运算符从既有类型组合出新类型熟练使用索引访问类型Type[Key]并能针对 22 个内置工具类型Utility Types按需选用写出高度可复用、类型安全的泛型代码。从类型创建类型类型系统的基本组合手段TypeScript 的核心能力之一就是从已有类型组合、操作、转换出全新的类型。这些手段不需要写任何运行时逻辑全部在类型层面完成因此不会产生任何运行时开销却能显著提升代码的可维护性与约束力。交集类型Intersection Types交集类型允许把多个类型组合进单一类型结果类型同时拥有所有被组合类型的所有成员type A { foo: number }; type B { bar: string }; type C A B; // Interseção de A e BA 与 B 的交集 const obj: C { foo: 42, bar: hello };交叉对象类型常用于叠加多个接口的能力例如把权限信息、审计信息等合并进一个实体类型。需要留意的是交集运算是累积的C必须同时满足A与B的全部属性约束。关于交集类型的更多细节可参考仓库中的 intersection-types.md。联合类型Union Types|联合类型定义可以是若干类型之一的值为变量预留了多种合法形态type Result string | number; const value1: Result hello; const value2: Result 42;联合类型与 TypeScript 的**收窄narrowing**机制天然配合通过typeof、in等检查可以在分支中把联合类型逐步收窄到具体成员从而获得精确的类型信息。联合类型与keyof结合还可以用来表达允许的键的集合详见仓库中的 union-type.md。映射类型Mapped Types映射类型允许遍历一个既有类型的每个属性逐一对属性做变换从而生成新类型。语法上借助keyof取得属性名集合再用[P in keyof T]进行遍历type MutableT { readonly [P in keyof T]: T[P]; }; type Person { name: string; age: number; }; type ImmutablePerson MutablePerson; // As propriedades tornam-se somente leitura属性变为只读上面的MutableT给每个属性都加上了readonly修饰符于是ImmutablePerson的所有字段都变成只读。仓库专门有一章 mapped-types.md 对此展开通过映射函数你可以把每个属性变换为数组、可空、只读等任意形态。例如原文档给出的经典写法——把每个属性变成由原类型组成的数组type MyMappedTypeT { [P in keyof T]: T[P][]; }; type MyType { foo: string; bar: number; }; type MyNewType MyMappedTypeMyType; const x: MyNewType { foo: [hello, world], bar: [1, 2, 3], };映射类型还有一组**修饰符modifiers**可以精确控制变换方向见仓库中的 mapped-type-modifiers.md修饰符含义示例readonly或readonly将属性标记为只读type ReadOnlyT { readonly [P in keyof T]: T[P] }-readonly移除只读使属性可写type MutableT { -readonly [P in keyof T]: T[P] }?将属性标记为可选type MyPartialT { [P in keyof T]?: T[P] }这三个写法分别对应内置工具类型ReadonlyT、MutableT自定义与PartialT的手工实现是理解内置工具类型底层原理的最佳起点。条件类型Conditional Types条件类型在类型层面引入逻辑分支以T extends U ? X : Y的形式依据T是否可赋值给U的结果选择X或Y。它等价于类型世界的三元表达式type ExtractParamT T extends (param: infer P) any ? P : never; type MyFunction (name: string) number; type ParamType ExtractParamMyFunction; // string上面这个例子同时用到了extends条件与infer推断当T匹配接收一个参数的函数形态时把参数类型推断为P并返回。条件类型的专项讲解见 conditional-types.md例如判断一个类型是否为数组type IsArrayT T extends any[] ? true : false; const myArray [1, 2, 3]; const myNumber 42; type IsMyArrayAnArray IsArraytypeof myArray; // Tipo true type IsMyNumberAnArray IsArraytypeof myNumber; // Tipo false条件类型还有两个进阶特性值得掌握分配式条件类型Distributive Conditional Types——当T是联合类型时条件会分别作用于联合的每一个成员再把结果合并回联合。仓库中的 distributive-conditional-types.md 给出典型示例type NullableT T extends any ? T | null : never; type NumberOrBool number | boolean; type NullableNumberOrBool NullableNumberOrBool; // number | boolean | nullnumber | boolean被逐成员展开各自加null最终得到number | boolean | null。这正是NonNullableT等工具类型的实现基础。infer关键字——在条件类型的extends分支中声明一个待推断类型变量用于从结构里提取类型。仓库中的 infer-type-inference-in-conditional-types.md 给出的例子type ElementTypeT T extends (infer U)[] ? U : never; type Numbers ElementTypenumber[]; // number type Strings ElementTypestring[]; // stringinfer U从数组类型中提取出元素类型。ParametersT、ReturnTypeT、AwaitedT等工具类型底层全部依赖infer它是高级类型编程的基石。索引访问类型Indexed Access TypesType[Key]与运行时用索引读取对象属性类似类型层面也可以通过索引访问另一个类型的属性类型语法为Type[Key]。这是从类型中取类型的最直接手段type Person { name: string; age: number; }; type AgeType Person[age]; // number索引不限于属性名字面量也支持数字索引——对元组tuple按位置取类型type MyTuple [string, number, boolean]; type MyType MyTuple[2]; // boolean注意 JavaScript 索引访问的对象属性在运行时行为同样适用于类型层面Person[name]与Person[age]各自精确返回对应属性的类型。索引访问类型还可以与keyof、联合索引如Person[name | age]组合实现取一组属性类型的效果。索引签名Index Signatures的底层规则可参见仓库中的 index-signatures.md——string、number、symbol都可以作为索引键类型且 JavaScript 会自动把数字索引转换为字符串索引k[1]与k[1]结果相同。更系统的索引类型讨论见 type-indexing.md。内置工具类型Utility Types完全参考TypeScript 标准库内置了一整套工具类型Utility Types覆盖了绝大多数常见的类型变换需求。下面按原文档顺序逐一讲解所有示例均可直接复制运行。AwaitedT递归地解包Promise类型取出最终 resolve 的值类型type A AwaitedPromisestring; // string对于嵌套 PromisePromisePromisenumber同样有效是处理异步函数返回类型的利器。PartialT把T的所有属性变为可选type Person { name: string; age: number; }; type A PartialPerson; // { name?: string | undefined; age?: number | undefined; }常用于更新操作入参不需要提供完整对象只提供要修改的字段。RequiredT与Partial相反把T中所有可选属性变为必选type Person { name?: string; age?: number; }; type A RequiredPerson; // { name: string; age: number; }ReadonlyT把T的所有属性标记为只读赋值会被编译器拒绝type Person { name: string; age: number; }; type A ReadonlyPerson; const a: A { name: Simon, age: 17 }; a.name John; // Inválido非法只读属性不可赋值它等价于手工映射类型{ readonly [P in keyof T]: T[P] }见 mapped-type-modifiers.md。RecordK, T构造一个键集合为K、每个值类型为T的对象类型。K通常是字符串字面量联合也可以放宽为stringtype Product { name: string; price: number; }; const products: Recordstring, Product { apple: { name: Apple, price: 0.5 }, banana: { name: Banana, price: 0.25 }, }; console.log(products.apple); // { name: Apple, price: 0.5 }Recordkeyof T, boolean这类用法在为每个属性维护一个开关标志的场景中非常常见。PickT, K从T中挑选指定的属性集K构成新类型type Product { name: string; price: number; }; type Price PickProduct, price; // { price: number; }适合对外暴露子集视图例如只把实体的公开字段暴露给外部调用方。OmitT, K与Pick互补从T中剔除指定的属性集Ktype Product { name: string; price: number; }; type Name OmitProduct, price; // { name: string; }典型场景是从完整实体派生出创建入参去掉id、createdAt等由系统生成的字段。ExcludeT, U从联合类型T中排除所有可赋值给U的成员type Union a | b | c; type MyType ExcludeUnion, a | c; // bExtractT, U与Exclude相反从T中提取所有可赋值给U的成员type Union a | b | c; type MyType ExtractUnion, a | c; // a | cExclude与Extract是分配式条件类型的直接产物二者连同NonNullable、ReturnType、Parameters等被 TypeScript 官方归类为预定义条件类型详见 predefined-conditional-types.md。NonNullableT从T中剔除null与undefinedtype Union a | null | undefined | b; type MyType NonNullableUnion; // a | b对于可选属性或来自外部API、配置文件的可空数据这是最常用的净化手段。ParametersT提取函数类型T的参数列表类型结果是一个元组tupletype Func (a: string, b: number) void; type MyType ParametersFunc; // [a: string, b: number]注意结果保留了参数名label因此[a: string, b: number]是一个带标签的具名元组。ConstructorParametersT提取构造函数类型T的参数列表同样返回元组class Person { constructor( public name: string, public age: number ) {} } type PersonConstructorParams ConstructorParameterstypeof Person; // [name: string, age: number] const params: PersonConstructorParams [John, 30]; const person new Person(...params); console.log(person); // Person { name: John, age: 30 }通过typeof Person取得类构造函数类型再配合ConstructorParameters与展开运算符...可以实现参数数组化的工厂调用模式。ReturnTypeT提取函数类型T的返回值类型type Func (name: string) number; type MyType ReturnTypeFunc; // number在依赖函数返回值推断下游类型时例如根据工厂函数推导实体类型非常有用。InstanceTypeT提取类类型T的实例类型class Person { name: string; constructor(name: string) { this.name name; } sayHello() { console.log(Olá, meu nome é ${this.name}!); } } type PersonInstance InstanceTypetypeof Person; const person: PersonInstance new Person(John); person.sayHello(); // Olá, meu nome é John!InstanceTypetypeof Person与直接使用Person类型等价但在泛型工厂接收构造函数、返回实例中它是必不可少的抽象手段。ThisParameterTypeT提取函数类型T中显式声明的this参数类型interface Person { name: string; greet(this: Person): void; } type PersonThisType ThisParameterTypePerson[greet]; // PersonPerson[greet]是一个带显式this参数的方法类型ThisParameterType能把这个this类型取出来。OmitThisParameterT与ThisParameterType互补移除函数类型T中的this参数得到去掉this后的普通函数类型function capitalize(this: String) { return this[0].toUpperCase() this.substring(1).toLowerCase(); } type CapitalizeType OmitThisParametertypeof capitalize; // () stringtypeof capitalize原本带有this: String参数经OmitThisParameter处理后变成零参数的() string。ThisTypeTThisTypeT本身不产生任何类型变换它只是上下文this类型的标记配合noImplicitThis编译选项让对象字面量内部的this获得类型检查type Logger { log: (error: string) void; }; let helperFunctions: { [name: string]: Function } ThisTypeLogger { hello: function () { this.log(some error); // Válido, pois log faz parte de this合法log 属于 this this.update(); // Inválido非法update 不在 this 类型中 }, };因为helperFunctions被声明为 ThisTypeLogger内部函数的this被推断为Logger于是this.log合法而this.update报错。这一机制常被用于配置对象、混入mixin等以对象组织方法、共享上下文的编程风格。字符串大小写变换Uppercase / Lowercase / Capitalize / Uncapitalize这组工具类型对字符串字面量类型做大小写变换属于 TS 4.1 引入的模板字面量类型配套能力type MyType Uppercaseabc; // ABCtype MyType LowercaseABC; // abctype MyType Capitalizeabc; // Abctype MyType UncapitalizeAbc; // abc它们通常配合模板字面量类型一起使用例如从userName推导出UserName等字段映射场景。NoInferTNoInferT是 TS 5.4 引入的工具类型作用是阻止编译器在泛型函数调用时对T做自动推断从而强制调用方显式给出或由其他参数决定该类型参数。先看不使用NoInfer的情况// Inferência automática de tipos dentro do escopo de uma função genérica. function fnT extends string(x: T[], y: T) { return x.concat(y); } const r fn([a, b], c); // O tipo aqui é (a | b | c)[]此处类型为 (a | b | c)[]这里T被[a, b]推断为a | b随后y: T也接受了c并把c并入返回类型导致结果类型意外扩张为(a | b | c)[]。用NoInfer包裹y的参数类型后// Exemplo de função que usa NoInfer para evitar inferência de tipo function fn2T extends string(x: T[], y: NoInferT) { return x.concat(y); } const r2 fn2([a, b], c); // Erro: Argumento de tipo c não é atribuível ao parâmetro do tipo a | b.此时T只能由x推断为a | by: NoInferT不再参与推断因此传入c会报类型不匹配错误。这一特性对让第一个参数决定类型、其余参数保持严格一致的 API 设计极有价值。组合实战用工具类型与泛型构建类型安全流水线单个工具类型往往解决单一需求而把它们与**泛型Generics**组合起来才能发挥类型操作的最大威力。仓库的 generics.md 系统讲解了泛型约束T extends ...、泛型类与高阶函数推断。下面是一个综合示例把本指南讲到的多个手段串联起来// 1) 用 Pick Partial 实现可选的更新入参 type Entity { id: number; name: string; createdAt: Date }; type UpdatePayloadT PartialPickT, Excludekeyof T, id | createdAt; type UserUpdate UpdatePayloadEntity; // { name?: string | undefined } // 2) 用 Omit Required 构造去掉可选字段的完整入参 type CreateUser OmitEntity, id | createdAt; // { name: string } // 3) 用 Parameters ReturnType 提取并复用函数签名 function fetchUser(id: number): PromiseEntity { /* ... */ return Promise.resolve({ id, name: a, createdAt: new Date() }); } type FetchParams Parameterstypeof fetchUser; // [id: number] type FetchResult AwaitedReturnTypetypeof fetchUser; // Entity自动解包 Promise // 4) 用 InstanceType 约束工厂函数 function createT(Ctor: new (...args: never[]) T): T { return new Ctor(); } type E InstanceTypetypeof Entity;通过这样层层组合你可以把实体 → 入参类型 → 返回值类型 → 实例类型整条数据链路都交给编译器校验从而让类型定义成为唯一的事实来源消除大量手写接口的重复与漂移。延伸阅读本指南对应的原文档是 website/src/content/docs/pt-br/book/type-manipulation.md英文版见 website/src/content/docs/book/type-manipulation.md是《The Concise TypeScript Book》全书的第 61 章。若要进一步深入可在同目录下继续阅读mapped-types.md——映射类型专项详解mapped-type-modifiers.md——映射类型修饰符conditional-types.md——条件类型基础distributive-conditional-types.md——分配式条件类型infer-type-inference-in-conditional-types.md——infer推断predefined-conditional-types.md——预定义条件类型总览generics.md——泛型与约束type-indexing.md——类型索引与 index-signatures.md掌握从类型创建类型、索引访问与工具类型这三板斧之后你便拥有了把业务约束翻译成编译期约束的完整工具箱——这正是高效 TypeScript 开发的核心能力。赞分享文档教程【免费下载链接】typescript-bookThe Concise TypeScript Book: A Concise Guide to Effective Development in TypeScript. Free and Open Source.项目地址https://gitcode.com/gh_mirrors/typ/typescript-book点击查看免费下载相关推荐The Concise TypeScript Book 类型操纵Type Manipulation完全指南从类型创建类型到内置工具类型实战The Concise TypeScript Book 类型操纵Type Manipulation完全指南从类型创建类型到内置工具类型实战 本指南以 Th文档教程The Concise TypeScript Book 类型操纵Type Manipulation全解从类型生成类型到实用工具类型实战The Concise TypeScript Book 类型操纵Type Manipulation全解从类型生成类型到实用工具类型实战 本指南以开源仓库文档教程《The Concise TypeScript Book》精读Type Manipulation 类型操作全解析——从组合、索引访问到 20 个内置工具类型《The Concise TypeScript Book》精读Type Manipulation 类型操作全解析——从组合、索引访问到 20 个内置工具类型文档教程上一篇4种高效方案解决TranslucentTB启动故障下一篇3个强力方案解决TranslucentTB启动故障创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。