TypeScript:never 类型的神奇妙用

在 TypeScript 中,never 是一个特殊类型,表示「永不存在的值类型」,通常用于表示不可能发生的情况。它适用于抛出异常、不返回值的函数或处理逻辑上永远不会出现的分支。

以下是它的简单用法和注意事项:

1. never 的用法

1、抛出异常的函数:当函数会抛出错误并终止执行时,返回类型应定义为 never。

🌰:

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

 2、死循环的函数:永远不会结束的函数(例如:无限循环)也可以使用 never 类型。

🌰:

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

3、类型保护中的检查:在类型缩小过程中,用 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);

2. never 的神奇

1、确保类型全面覆盖:在处理 switch 或多类型分支时,never 可用于强制检查是否所有可能的分支都被覆盖,帮助捕获遗漏的情况。

🌰:假设有个表示用户状态的联合类型 UserStatus:

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}`);}
}

在 switch 语句的 default 分支中,我们定义了一个 exhaustiveCheck 变量,类型为 never,并将 status 赋值给它。TypeScript 会在编译时检查,如果 status 不是 never 类型(即还存在未处理的情况),会触发编译错误。

比如:未来在 UserStatus 中添加新的状态,例如 suspended,但没有在 switch 语句中处理它,TypeScript 会报错:

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

这种方式确保了新增状态时的类型全面覆盖,有助于维护代码的健壮性和可读性。

2、类型收窄的辅助:never 可以帮助 TS 判断哪些代码路径无法访问,从而优化代码检查和类型收窄。

🌰:

// 在类型约束中,表示参数的类型不是某一个类型,比如:类型除了 number 之外都OK
type MyExclude<T, U> = T extends U ? never : T;
// function isNumber<T>(x: T extends number ? never : T) {}
function isNumber<T>(x: MyExclude<T, number>) {}
isNumber('123')
isNumber({})
isNumber(true)
isNumber(111)

3. 判断 never 类型

在 TypeScript 中,当使用条件类型 T extends never ? true : false 直接判断 never 类型时,得到 never 而不是 true。

1、为什么会这样呢?

在条件类型中,当 T 是联合类型时,TypeScript 会对 T 中的每个成员独立应用条件(即分配式条件类型)。但是 never 是一个“空的联合类型”,没有成员,因此 TypeScript 无法真正地应用条件,它直接返回 never。

2、分配式条件类型

条件类型在遇到联合类型时,会逐一分配并进行条件判断,即所谓的分配式。不过,never 并不属于任何集合,因此在分配式条件下,会直接返回 never,而不会像其他类型一样返回 true 或 false。

3、解决方法:

为了让条件类型正确地判断 never,可以将 T 包装在元组中,以防止分配式条件类型的影响:

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

这样会强制 T 作为一个整体进行判断,因此 never 就会得到 true。 

🌰:

type Test1 = IsNever<never>; // true
type Test2 = IsNever<string>; // false
type Test3 = IsNever<undefined>; // false
type Test4 = IsNever<any>; // false

4. 注意事项

1、避免滥用:never 仅适用于不可能有结果的情况;如果函数可能有返回值,使用 void 更合适。

2、和 void 的区别:void 表示函数无返回值,但仍会返回 undefined,而 never 表示函数根本不会返回。

3、使用在类型收窄中:never 可以帮助 TypeScript 识别和优化代码分支,若分支逻辑不全,编译器会警告。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1538.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Redis-结构化value对象的类型

文章目录 一、Redis的结构化value对象类型的介绍二、Redis的这些结构化value对象类型的通用操作查看指定key的数据类型查看所有的key判断指定key是否存在为已存在的key进行重命名为指定key设置存活时间pexpire与expire 查看指定Key的存活时间为指定key设置成永久存活 三、Redis…

解密美国 VPS 主机的核心优势与未来发展

在全球网络需求不断增长的今天&#xff0c;许多企业和开发者都在寻找更灵活、安全、性能优异的主机解决方案。美国 VPS 主机凭借其强大的技术支持和广泛的网络连接&#xff0c;成为国际用户的热门选择。本文将深入探讨美国 VPS 主机的核心优势、其在网络应用上的独特表现&#…

XSS小游戏【1-13关】

第一关 Payload&#xff1a;<script>alert(1)</script> 第二关 Payload&#xff1a;keyword<script>alert(1)</script> 发现没有成功&#xff0c;F12发现需要闭合input 标签 再次输入payload&#xff1a;aaa"><svg οnlοadalert(1)> …

Spring Boot框架:校园社团信息管理的现代化解决方案

3系统分析 3.1可行性分析 通过对本校园社团信息管理系统实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本校园社团信息管理系统采用SSM框架&#xff0c;JAVA作…

uniapp推送配置流程

Dcloud Dcloud注册账号 个推 了解即可 注册个推账号 ios配置流程 需配置含有推送的描述文件以及p8证书 配置推送证书 ios证书配置报技术错误&#xff08;参数错误&#xff09; TeamID-苹果开发者账号唯一的ID 安卓需配置多厂商 小米手机需要配置小米厂商 华为手机则需…

JavaEE初阶---网络原理之TCP篇(二)

文章目录 1.断开连接--四次挥手1.1 TCP状态1.2四次挥手的过程1.3time_wait等待1.4三次四次的总结 2.前段时间总结3.滑动窗口---传输效率机制3.1原理分析3.2丢包的处理3.3快速重传 4.流量控制---接收方安全机制4.1流量控制思路4.2剩余空间大小4.3探测包的机制 5.拥塞控制---考虑…

单细胞数据分析(一):10X数据生成seurat数据对象

文章目录 介绍加载R包数据链接导入数据过滤细胞:移除双重细胞合并所有seurat数据对象输出结果系统信息介绍 在单细胞基因组学研究中,Seurat是一个流行的R包,用于单细胞基因表达数据的分析和探索。以下是如何从10X基因注释数据生成Seurat数据对象,并对该数据进行过滤的步骤…

了解SQLExpress数据库

SQLExpress&#xff08;Microsoft SQL Server Express&#xff09;是由微软公司开发的一款免费且轻量级的数据库管理系统。以下是关于SQLExpress的详细解释&#xff1a; 一、定义与特点 定义&#xff1a; SQLExpress是Microsoft SQL Server的一个缩减版或基础版&#xff0c;旨在…

C++ 魔法三钥:解锁高效编程的封装、继承与多态

快来参与讨论&#x1f4ac;&#xff0c;点赞&#x1f44d;、收藏⭐、分享&#x1f4e4;&#xff0c;共创活力社区。 目录 &#x1f4af;前言 &#x1f4af;封装 1.封装概念 2.封装格式 3.封装的原理 4.封装的作用 &#x1f4af;继承 1.继承的概念 2.继承格式 3.继承的…

开源 AI 智能名片 2 + 1 链动模式 S2B2C 商城小程序中积分使用价值的拓展策略

摘要&#xff1a;本文围绕开源 AI 智能名片 2 1 链动模式 S2B2C 商城小程序&#xff0c;深入探讨其积分使用价值的丰富策略。详细分析积分兑换礼品、会员升级、积分抵现等方式在该特定商城小程序环境下的应用特点、存在问题及对用户和商城的影响&#xff0c;旨在为商城的优化运…

UE4安卓Gradle工程中的libUE4.so的生成原理

流程图 流程图放在最前面&#xff0c;下面是讲解。 libUE4.so 问&#xff1a;在UE4安卓开发中&#xff0c;libUE4.so即是符号表&#xff0c;又是引擎代码native&#xff0c;是吗&#xff1f; 答&#xff1a;是的&#xff0c;libUE4.so在UE4安卓开发中既包含符号表&#xff0c;…

Java线程池的核心内容详解

文章内容已经收录在《面试进阶之路》&#xff0c;从原理出发&#xff0c;直击面试难点&#xff0c;实现更高维度的降维打击&#xff01; 目录 文章目录 目录Java线程池的核心内容详解线程池的优势什么场景下要用到线程池呢&#xff1f;线程池中重要的参数【掌握】新加入一个任…

Pandas DataFrame学习

1.DataFrame定义 DataFrame 是 Pandas 中的另一个核心数据结构&#xff0c;用于表示二维表格型数据。DataFrame 是一个表格型的数据结构&#xff0c;它含有一组有序的列&#xff0c;每列可以是不同的值类型&#xff08;数值、字符串、布尔型值&#xff09;。DataFrame 既有行索…

如何在创建完fb公共主页后添加管理员防止封号?

在创建Facebook公共主页后&#xff0c;及时添加备用管理员是非常重要的。这可以帮助防止由于个人账号被封或其他限制因素导致无法继续管理公共主页的情况。以下是关于如何添加管理员及接受邀请的详细步骤。 Facebook公共主页的角色介绍 在Facebook公共主页上&#xff0c;有五种…

无人机避障——使用三维PCD点云生成的2D栅格地图PGM做路径规划

着重介绍通过对三维 PCD 点云进行处理生成 2D 栅格地图 PGM&#xff0c;而后将该 PGM 地图充分运用到无人系统路径规划之中&#xff0c;使得无人机能够依据此规划合理避开飞行路线上可能出现的障碍物。&#xff08;解决如何使用PGM的问题&#xff09; Hybrid A*算法 参考博客…

YOLOv10改进策略【注意力机制篇】| WACV-2024 D-LKA 可变形的大核注意 针对大尺度、不规则的目标图像

一、本文介绍 本文记录的是利用D-LKA模块优化YOLOv10的目标检测网络模型。D-LKA 结合了大卷积核的广阔感受野和可变形卷积的灵活性&#xff0c;有效地处理复杂的图像信息。本文将其应用到v11中&#xff0c;并进行二次创新&#xff0c;使网络能够综合多种维度信息&#xff0c;更…

人工智能中的机器学习和模型评价

文章目录 1.监督学习1.1线性回归1.2KNN算法1.3支持向量机 2.无监督学习2.1K-means聚类2.2FCA主成分分析 机器学习是人工智能的一个分支&#xff0c;它使计算机系统能够从数据中学习并做出决策&#xff0c;而无需进行明确的编程。它涉及到开发算法和技术&#xff0c;使计算机能够…

HomeAssistant自定义组件学习-【二】

#要说的话# 前面把中盛科技的控制器组件写完了。稍稍熟悉了一些HA&#xff0c;现在准备写窗帘控制组件&#xff0c;构想的东西会比较多&#xff0c;估计有些难度&#xff0c;过程会比较长&#xff0c;边写边记录吧&#xff01; #设备和场景环境# 使用的是Novo的电机&#xf…

Docker Swarm简介

注意事项 Swarm 模式是用于管理 Docker 守护进程集群的一项高级特性。如果你打算将 Swarm 用作生产运行时环境&#xff0c;那就使用 Swarm 模式。如果你不打算使用 Swarm 进行部署&#xff0c;可改用 Docker Compose。如果正在为 Kubernetes 部署进行开发&#xff0c;可以考虑使…

JVM 运行时数据区

JVM整体架构 可以分为三层&#xff1a; 1 JVM外部&#xff0c;从源文件到Class文件&#xff0c;再装载到JVM 2 JVM运行时数据区&#xff0c;相当于就是避风港、运行的大后方。给执行程序提供后勤。 3 执行引擎层。和运行时数据区交互&#xff0c;完成执行任务。 运行时数据…