当前位置:

首页 > 编程开发 > TypeScript中never类型的神奇妙用

TypeScript中never类型的神奇妙用

TypeScript中的never类型表示永不存在的值,用于抛出异常、无限循环或类型收窄中的穷尽检查,可强制覆盖所有类型分支,避免遗漏。条件类型判断时需用元组包装以正确识别never,避免分配式特性带来的误判。

在 TypeScript 的类型系统里,never 绝对算得上一个“特立独行”的存在——它代表的是“永不存在的值类型”。简单说,就是那些根本不可能有结果的情况,比如抛异常的函数、无限循环,或者是在类型收窄时逻辑上永远走不到的分支。下面咱们就好好聊聊它的用法、妙处,以及一些容易踩坑的地方。

1. never 的用法

第一,抛出异常的函数。 当函数执行到一半直接 throw 一个错误,程序就此终止,不会再返回任何值,这时候返回类型就该写成 never。

function throwError(message: string): never {
  throw new Error(message);
}

第二,死循环的函数。 比如一个永远跑不停的 while(true),它永远不会结束,自然也不会返回——never 正好适合它。

function infiniteLoop(): never {
  while (true) {}
}

第三,类型保护中的穷尽检查。 在类型缩小(type narrowing)的过程中,用 never 来标记那些理论上不可能出现的分支,能帮我们捕捉遗漏的情况,让代码更严谨。

function handleValue(value: string | number) {
  if (typeof value === 'string') {
    console.log('String value');
  } else if (typeof value === 'number') {
    console.log('Number value');
  } else {
    // 如果 value 类型是 never,编译器会检查这里的情况是否可能发生
    const _exhaustiveCheck: never = value;
    throw new Error('Unexpected type: ' + value);
  }
}
handleValue('string');
handleValue(1);
handleValue(true);

TypeScript中never类型的神奇妙用

2. never 的神奇

1. 确保类型全面覆盖。 在处理 switch 或多类型分支时,never 可以作为一个“强制检查工具”——如果你漏掉了某个分支,TypeScript 会在编译时报错。举个例子,有一个表示用户状态的联合类型:

type UserStatus = "active" | "inactive" | "banned";

function handleUserStatus(status: UserStatus) {
  switch (status) {
    case "active":
      console.log("User is active");
      break;
    case "inactive":
      console.log("User is inactive");
      break;
    case "banned":
      console.log("User is banned");
      break;
    default:
      // 强制类型检查是否已全面覆盖所有情况
      const exhaustiveCheck: never = status;
      throw new Error(`Unhandled status: ${status}`);
  }
}

关键就在 default 分支里:我们把 status 赋值给一个 never 类型的变量。如果后续 UserStatus 新增了一个成员(比如 'suspended'),而 switch 没处理它,TypeScript 就会报错——因为此时 status 不再是 never,而变成了 'suspended',赋值操作不通过。

type UserStatus = 'active' | 'inactive' | 'banned' | 'suspended';

TypeScript中never类型的神奇妙用

这样一来,只要有人新增了类型成员,编译器就会立刻提醒你“该补全分支了”,代码健壮性自然就上去了。

2. 类型收窄的辅助。 never 还能帮 TypeScript 判断哪些代码路径永远无法到达,从而优化类型检查和代码推理。比如可以用它来定义一个“排除某类型”的工具:

type MyExclude = T extends U ? never : T;

function isNumber(x: MyExclude) {}
isNumber('123')  // ok
isNumber({})     // ok
isNumber(true)   // ok
isNumber(111)    // 报错,因为 111 被 exclude 掉了

3. 判断 never 类型

这里有一个容易让人困惑的点:直接用条件类型判断 never 时,得到的结果往往不是你想要的。比如 T extends never ? true : false,当 T 是 never 时,结果竟然是 never 而不是 true。

为什么? 因为条件类型具有“分配式”(distributive)特性——当 T 是联合类型时,TypeScript 会把联合的每个成员分别代入条件。而 never 实际上是一个“空的联合类型”,没有成员,所以分配过程无法进行,直接返回 never。

怎么解决? 把 T 包在元组里,阻止分配式行为:

type IsNever = [T] extends [never] ? true : false;

这样 T 会作为一个整体参与判断,never 就能正确返回 true 了:

type Test1 = IsNever;       // true
type Test2 = IsNever;      // false
type Test3 = IsNever;   // false
type Test4 = IsNever;         // false

4. 注意事项

使用 never 时,有几个关键点需要留意:

  • 别滥用。 它只适用于“彻底没有结果”的场景。如果函数只是没有显式返回值(比如返回 undefined),用 void 更妥当。
  • 区别 void。 void 表示函数没有返回值,但调用后仍会得到 undefined;而 never 表示函数根本不会正常结束——要么抛异常,要么永远运行。
  • 善用类型收窄。 在穷尽检查分支时,never 能帮助 TypeScript 识别和优化代码路径。如果某个分支逻辑没有覆盖全,编译器会主动提醒你,防患于未然。
本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
作者最新文章
编程开发
相关文章 更多
音述AI生成音乐音质差该怎么调整参数
音述AI生成音乐音质差该怎么调整参数

本文详解音述AI生成音乐音质不佳时的调整方法,包括如何细化生成描述、逐项调整风格与乐器参数、简化编制以减少混浊,以及检查导出设置,帮助用户获得更清晰的音频结果。

会声会影提升视频清晰度与提取音频全攻略
会声会影提升视频清晰度与提取音频全攻略

面向使用会声会影进行视频剪辑的用户,解决素材模糊不清及背景音乐获取难题。本文详解锐化滤镜、NewBlue锐化与清晰度参数的区别及适用场景,指导如何根据画面明暗选择最佳增强方案;同时演示通过分离音频或画外音录制功能提取视频音乐及系统声音的操作步骤;最后分享利用色调曲线和叠加混合模式在视觉上提升普通分辨率素材清晰度的技巧,帮助用户高效优化视听效果。

会声会影安装报错Error 1402的注册表权限修复与清理方案
会声会影安装报错Error 1402的注册表权限修复与清理方案

面向在Windows系统安装会声会影时遭遇Error 1402错误的用户,该错误通常由注册表权限混乱、旧版本残留或配置失败引起。本文提供四种解决路径:首先通过注册表编辑器修改HKEY_LOCAL_MACHINE下UserData项的所有者及权限为Administrators;其次使用专用工具或手动清理未卸载干净的注册表残留;针对特定插件配置失败,建议单独下载安装对应组件;若因系统底层问题导致无法写入注册表,则需考虑重装系统。

Nero Motion Tracker文件导出
Nero Motion Tracker文件导出

学习如何在Nero Motion Tracker中导出处理后的视频。本文逐步讲解如何确认追踪效果、选择导出片段、执行Export操作以及将项目移交Nero Video,帮助新手快速生成带隐私保护的视频文件。

blender更新到哪个版本了最新版本号查询教程
blender更新到哪个版本了最新版本号查询教程

想知道Blender更新到哪个版本了?本教程教你通过软件内部“关于”窗口查看准确版本号,并访问官方下载页核对最新稳定版与LTS版本。提供版本对照方法与更新前的兼容性检查建议,确保项目安全。

charles配置手机教程及连接设置方法
charles配置手机教程及连接设置方法

手把手教你配置 Charles 手机代理。包含电脑IP获取、iPhone HTTP代理设置、CA证书安装信任及SSL代理开启步骤,解决手机无法联网或HTTPS加密问题,适用于iOS与安卓基础调试。

winrar如何设置成中文界面的详细操作步骤
winrar如何设置成中文界面的详细操作步骤

WinRAR安装后显示英文怎么办?本文详解通过Options菜单切换简体中文界面的操作流程,包含重启验证方法及语言包缺失时的处理建议,帮助用户快速恢复熟悉的中文操作环境。

blender隐藏快捷键大全及显示恢复操作教程
blender隐藏快捷键大全及显示恢复操作教程

Blender中按H键隐藏对象后如何恢复?本文详解对象模式与编辑模式的隐藏区别,介绍Shift+H隔离显示、小键盘/局部视图及Outliner手动恢复方法,解决模型突然消失的困扰。

Windows11优化后系统不稳定如何恢复默认设置
Windows11优化后系统不稳定如何恢复默认设置

Windows 11优化后出现卡顿或报错?不要急于重装。本文详解如何先手动还原电源与视觉设置,再利用系统还原点撤销注册表改动,最后通过安全模式排查干扰,必要时才考虑重置此电脑。

goldwave怎么录音电脑声音设置及操作教程
goldwave怎么录音电脑声音设置及操作教程

想在GoldWave中直接录制电脑播放的声音?关键在于正确配置Windows的“立体声混音”或回录设备。本文分步讲解如何查找并启用系统回录源,在GoldWave中切换输入设备,以及通过测试录音避免录入麦克风杂音,确保内录清晰准确。

查看更多
精品专题 更多
装机必备
装机必备

正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

Windows
Windows

正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

PDF教程
PDF教程

正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

Mac软件 更多
IntelliJ IDEA macOS版
IntelliJ IDEA macOS版
Mac

IntelliJ IDEA 是 JetBrains 推出的专业集成开发环境,重点服务于 Java、Kotlin 与 JVM 项目开发。软件集成代码补全、静态检查、重构、调试、测试、版本控制及构建工具,并可借助插件扩展语言和框架支持。

PyCharm macOS版
PyCharm macOS版
Mac

JetBrains PyCharm 是面向 Python 开发者的集成开发环境,提供智能补全、代码检查、重构、调试、测试、版本控制及虚拟环境管理功能。Mac 版兼容 Intel 与 Apple 芯片,核心功能可免费使用。

WebStorm macOS版
WebStorm macOS版
Mac

JetBrains WebStorm 是面向 JavaScript、TypeScript 和现代 Web 技术的专业集成开发环境,可智能理解项目结构,提供代码补全、重构、错误检查、运行调试、测试及 Git 工具。

WINDOWS 更多
IntelliJ IDEA Windows版
IntelliJ IDEA Windows版
Windows

JetBrains IntelliJ IDEA 是以 Java、Kotlin 和 JVM 项目为核心的专业集成开发环境,提供智能补全、代码检查、安全重构、调试、测试、版本控制及构建工具集成。统一发行版的核心功能可免费用于商业和非商业项目,

PhpStorm Windows版
PhpStorm Windows版
Windows

PhpStorm 是 JetBrains 面向 PHP 与现代 Web 开发打造的专业集成开发环境,提供代码补全、静态检查、重构、调试、测试、数据库、版本控制及前端语言支持。Windows 用户可直接下载安装程序,

PyCharm Windows版
PyCharm Windows版
Windows

PyCharm 是 JetBrains 推出的 Python 集成开发环境,提供智能代码补全、错误检查、重构、调试、测试、Git、终端及 Jupyter Notebook 支持。统一版安装后可体验 30 天 Pro 功能,