The Concise TypeScript Book:彻底理解 void 类型——函数无返回值场景的正确类型注解
文档教程【免费下载链接】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点击查看免费下载void是 TypeScript 内置原始类型之一专门用于标注不返回任何值的函数。本文以 The Concise TypeScript Book本仓库website/src/content/docs/book/void-type.md章节为核心骨架结合仓库中 内置类型原始类型、类型系统探索、never 类型、strictNullChecks 等章节系统讲解 void 的定义、典型用法、与 undefined/never 的边界以及它在泛型、类方法、回调函数中的实际应用帮助你写出类型准确、可维护的 TypeScript 代码。一、void 的定义标注不返回值的函数在 void-type.md 章节中原书对 void 给出了一句最核心的定义void类型用于表示一个函数不返回任何值。换句话说当你声明一个只执行副作用打印日志、修改状态、调用其他函数而不产生返回结果的函数时应当把它的返回类型标注为void。原书给出的最小示例是const sayHello (): void { console.log(Hello!); };这里的sayHello函数体内部只调用console.log没有任何return语句因此它的返回类型就是void。在 类型注解 章节中原书强调返回类型注解可以添加到函数上并建议先写出返回类型再考虑实现有助于你从类型层面思考函数void正是这类以副作用为主、无返回结果的函数最常用的返回类型注解。void 属于内置类型原始类型在 built-in-type-primitives.md 中void 与number、string、boolean、null、undefined、symbol、bigint、any、never一起被列为 TypeScript 的内置类型原始类型书中对其定位是void表示任何类型的缺失the absence of any type。它通常用作不返回值函数的返回类型。这个定位说明两点第一void 不是值而是类型层面的空缺第二它的主战场是函数返回类型。下面我们逐一展开它的典型使用场景。二、void 的典型使用场景1. 普通函数只执行副作用最常见的模式是事件处理、日志输出、状态更新这类调用后不关心返回值的函数const logUser (name: string): void { console.log(User: ${name}); }; const updateState (count: number): void { // 假设这里更新某个外部状态 // ... };2. 类方法与接口方法void 无处不在在仓库的 class.md 章节中大量类方法都以void作为返回类型。例如书中的示例class Person { public sayHi(): void { console.log(Hi!); } }再如抽象类中声明抽象方法让子类强制实现无返回值的行为契约abstract class Animal { abstract makeSound(): void; } class Dog extends Animal { makeSound(): void { console.log(Woof!); } }在 接口与类型 和 类型合并与扩展 章节中接口方法也常以void作为返回值声明例如greet(): void、eat(): void这说明void在定义类型契约时是描述动作而非结果的标准写法。3. 泛型函数约束输入、忽略输出在 泛型 章节中void 经常与泛型搭配使用泛型参数负责约束输入void负责声明输出为空。书中第一个例子通过extends约束泛型参数必须具有length属性函数本身不返回值const printLen T extends { length: number }(value: T): void { console.log(value.length); }; printLen(Hello); // 5 printLen([1, 2, 3]); // 3 printLen({ length: 10 }); // 10 printLen(123); // Invalidnumber 没有 length 属性另一个例子展示了 void 返回类型配合泛型上下文收窄generic contextual narrowing的典型写法函数接受任意类型T在函数体内用typeof判断收窄类型但函数整体不返回值function processT(value: T): void { if (typeof value string) { // 此处 value 被收窄为 string console.log(value.length); } else if (typeof value number) { // 此处 value 被收窄为 number console.log(value.toFixed(2)); } } process(hello); // 5 process(3.14159); // 3.144. 回调与函数类型void 作为返回值类型占位符在 others.md 章节中void 也出现在函数类型定义中例如回调类型type FeedT (animal: T) void;。由于 JavaScript 中允许丢弃函数参数见 探索类型系统 中的说明例如[1,2,3].map((element, _index, _array) element x)一个返回void的回调位置也可以传入返回具体值的函数——TypeScript 会认为调用方不关心返回值这是void作为函数类型返回值时独有的宽容语义。三、void 与 undefined、never 的区别这是 TypeScript 初学者最容易混淆的一组类型。原书在 void-type.md 只讲了void 表示不返回值但结合仓库其他章节可以理清完整边界void vs undefinedundefined是具体的值一个变量确实被赋值成了undefined或一个函数显式return undefined。它属于原始类型undefined类型的变量只能存放undefined这个值。void是类型层面的空缺表示函数不会有返回值。在 探索类型系统 的赋值规则示例中可以看到二者的差异let g: void; let g1: any; g 1; // Invalidvoid 不能接受除 any 外的任何类型赋值 g g1; // Valid只有 any 可以赋给 void书中特别注释void 不能从任何类型赋值进来也不能赋值给除 any 以外的任何类型void is not assignable to or from anything except any。void vs nevernever 类型 章节指出never表示永远不会出现的值用于标注永远不会正常返回的函数——要么死循环要么直接抛错const infiniteLoop (): never { while (true) { // 永不退出 } }; const throwError (message: string): never { throw new Error(message); };与 void 的关键区别在于对比维度voidneverundefined语义函数正常结束但不返回任何值函数永远不会结束或必然抛错显式返回undefined值典型场景副作用函数、事件处理死循环、抛错函数、穷尽性检查显式return undefined是否可被赋值只接受any赋值什么都不接受f 1报错只接受undefined自身never 章节中还展示了二者联动的经典模式——穷尽性检查exhaustiveness check函数返回类型声明为void而在switch的default分支把不可能出现的值收窄为never一旦未来有人新增了未处理的分支TypeScript 会立刻报错type Direction up | down; const move (direction: Direction): void { switch (direction) { case up: // move up break; case down: // move down break; default: const exhaustiveCheck: never direction; throw new Error(Unhandled direction: ${exhaustiveCheck}); } };这里move的返回类型是void正常路径不返回值而default分支使用never确保枚举被穷尽覆盖两种类型各司其职。四、strictNullChecks 对 void 的影响仓库的 strictnullchecks.md 章节讲述了strictNullChecks编译器选项开启后变量只能显式声明为null | undefined联合类型时才能接收null/undefined赋值否则编译器直接报错。该选项与 void 的关系在 探索类型系统 中有明确结论注意当开启strictNullChecks时null和undefined的处理方式与void类似否则它们的行为与never类似。换句话说在开启strictNullChecks的项目里undefined与void一样被视为类型层面的空缺不能随意赋给需要具体值的变量从而避免大量运行时undefined引发的隐性 bug在关闭该选项时null/undefined可以赋值给任何类型行为类似never那样隐身类型系统对空值的约束大幅放松这也是现代项目普遍要求开启strictNullChecks的原因。因此当你声明一个: void的函数时即使函数体写return;或return undefined;也不会破坏类型契约但在开启严格空值检查时切勿把void类型的函数结果赋值给需要具体值的变量。五、函数返回类型对比的规则佐证在 探索类型系统 的TypeScript 基础比较规则中void 还参与函数类型的兼容性判断type X (a: number) void; type Y (a: number) void; let x: X (j: number) undefined; let y: Y (k: number) undefined; y x; // Valid x y; // Valid两个参数类型相同、返回类型同为void的函数类型可以互相赋值。而当返回类型不一致时例如一个返回undefined、一个返回number互相赋值就会报错仓库原文标注为 Invalid。这印证了void 作为返回类型参与比较时要求返回类型保持一致不能随意混用void与具体返回类型。六、最佳实践小结结合原书 void-type.md 及仓库各章节可以总结出以下实战建议副作用函数一律标注: void日志、事件处理、状态更新、命令式操作等不关心返回值的函数显式声明void能向读者和编译器明确这个函数没有产出。接口与抽象方法用void表达行为契约参见 class.md 中的makeSound(): void、greet(): void等写法。区分void/undefined/never正常结束不返回值用void显式返回undefined值用undefined死循环或必然抛错的函数用never详见 never-type.md。配合strictNullChecks使用在严格模式下void与null/undefined的处理保持一致空值不再能悄悄渗透进代码详见 strictnullchecks.md。善用 void never 的穷尽性检查在switch的default分支用never捕获未处理情况这是原书在 never 章节给出的高价值模式。泛型 void用泛型约束输入、用void声明无输出是工具函数如printLen的常见写法详见 generics.md。本文内容以仓库中意大利语翻译版章节 it-it/book/void-type.md原文为意大利语与英文版 book/void-type.md 对应为骨架展开所有代码与结论均可在本仓库对应章节中查证。赞分享文档教程【免费下载链接】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深入理解 void 类型——无返回值函数的正确标注方式The Concise TypeScript Book深入理解 void 类型——无返回值函数的正确标注方式 导读 本文以《The Concise Type文档教程The Concise TypeScript Book 精读void 类型——无返回值函数的类型契约The Concise TypeScript Book 精读void 类型——无返回值函数的类型契约 导读 在 TypeScript 的类型系统中 void文档教程The Concise TypeScript Book 实战指南理解 void 类型——为不返回值的函数建立正确的类型契约The Concise TypeScript Book 实战指南理解 void 类型——为不返回值的函数建立正确的类型契约 void 是 TypeScri文档教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考