- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我现在已经在互联网上搜索了为什么引入 never
类型的解释。 TypeScript 手册和 TypeScript Deep Dive 都解释了它是什么以及其他一些文章。但是,它们都没有解释为什么要使用 never
类型以及它解决的问题。大多数示例显示代码,其中编译器已经推断出 never
,那么为什么我必须分配类型?它解决什么。是否“只是”向智能感知发出我之后可以做什么的信号(即什么都不做——这可能足够有用)。编译器使用这些信息做什么?一如既往,解释“什么”和“如何”可能会帮助人们做事,但只有“为什么”才能让他们理解。
最佳答案
never
type 是 bottom type 的 TypeScript 表示来自 type theory .因此,如果您正在寻找 never
的动机和用途在 TypeScript 中,您可能希望了解计算机科学中的底层类型。
“为什么将 never
引入 TypeScript”的规范答案可能最好通过分析对 the pull request that introduced it 的评论找到以及它解决的两个问题:a request for a bottom type , 和 request to better handle unreachable function returns .
开发人员的主要用途是为函数(或函数的一部分)提供一个类型,它根本不返回任何值,甚至不返回 undefined
。 .比较这些功能:
function u(): undefined {
return;
}
const uRet = u();
console.log(typeof uRet); // undefined
function v(): void { }
const vRet = v();
console.log(typeof vRet); // undefined
返回undefined
值,具有以下功能:
function throws(): never {
throw new Error();
}
const tRet = throws();
console.log(typeof tRet); // does not run
function loops(): never {
while (true) { }
}
const lRet = loops();
console.log(typeof lRet); // does not run
由于异常或无限循环,根本不返回值。 never
type 允许开发人员和编译器对永远无法运行的代码段进行推理。
never
还有其他用途但我不会尝试列举它们,因为您已经知道代码示例。检查 TypeScript standard library 很有启发性找到never
的地方出现。
最后,当你问
Most of the examples show code, where the compiler already infers
never
, so why do I have to assign the type?
请注意,即使在编译器推断出 never
的情况下对你来说,它以与 string
相同的方式存在于语言中很有用。即使在编译器推断时也是有用的。这似乎是一个不同的问题,关于您何时可能想要显式注释类型而不是让编译器推断它们,反之亦然。但是这篇文章已经很长了,这可能在其他地方得到了回答。
希望对您有所帮助;祝你好运!
编辑:程序员使用 never
的原因有很多,尽管许多程序员可能永远不需要使用它。让我列举一些我能想到的原因:
如果您正在为一个函数抛出异常而不是返回的 JavaScript 库编写类型,那么没有 never
就无法做到这一点。 .
通用类型参数默认为 {}
当编译器无法推断出它们时。它有点“无法打开”,因为 {}
与(几乎)所有值兼容。在某些情况下,您希望它“失败关闭”并使其与任何值兼容。您可以使用 never
作为默认参数。
任何类型的联合T
与 never
只是T
, 和 T
的交集与 never
是never
.这些规则(以及其他规则)让开发人员可以构建相当复杂的类型函数,如果没有 never
,这些函数将变得更加困难或不可能。 .例如,这里是 Diff<T,U>
:
type Diff<T extends string, U extends string> =
({ [P in T]: P } & { [P in U]: never } & { [x: string]: never })[T];
这是一个类型函数,接受字符串文字的并集 T
和字符串文字的并集 U
, 并返回 T
中所有值的并集U
中不存在.
除其他外,您可以使用它从类型中删除属性:
type Foo = { a: string, b: number, c: boolean };
type FooWithoutB = Pick<Foo, Diff<keyof Foo, 'b'>>;
// equivalent to { a: string, c: boolean }
有点像数学中的数字零。你并不需要它;许多文化在没有零概念的情况下相处得很好。但它非常有用,可以让您轻松表达想法,否则这些想法会很麻烦或不可能。
希望这更引人注目?无论如何,再次祝你好运。
关于typescript - 为什么在 TypeScript 中引入 `never` 类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49219531/
在开始之前,我想指出的是,我已经通过Google进行了一次诚实而真实的搜索,涉及范围很广,无法找到。 我需要(对于我正在开发的项目)所有Delphi(从2007年到最新发布的版本,我不再支持任何早于2
我正在使用 RPM 将 Liquibase 数据库迁移添加到我们当前的产品部署中,并正在寻找一些有关如何实现我的预期目标的建议/技巧。 最好,RPM 能够安装在全新且 Shiny 的开发人员环境以及现
我目前正在使用一本书学习 UITableViewCell。为了在滚动时重用单元格,作者要求修改原始代码以包含一个if()。检查特定重用标识符的单元格是否存在的语句。但是,在添加 if() 之后语句,X
在 C++ 中引入 protected 访问说明符背后的基本原理是什么。举个例子会有帮助。 最佳答案 对于这类问题,我推荐 Bjarne Stroustrup 的The Design And Evol
我正在尝试使用模板参数中给定的维度和类型创建一个可重用的矩阵类。结构本身就是: template struct Matrix { T elements[N* M]; }; 当我尝试实现矩阵乘
我有一个简单的查询: $query1="SELECT * FROM wp_users WHERE now() < (last_login + INTERVAL 6 month)"; $resu
在 Ioke doc 中,ISpec 测试包含在文档中,参见 ioke.org/dok/index.html 这如何用 Ruby 的 RSpec 和 RDoc(或 SDoc)来完成?我找不到任何命令行
在客户端/服务器通信中,我看到来自客户端的 TCP ZeroWindow。 在这种情况之后预期的场景是什么(设置和发送什么标志)? 以下是我可能得到的日志。在这种情况下,服务器发送 RST 数据包来终
来自wikipedia关于 Lambda 函数和表达式的文章: users will often wish to define predicate functions near the place w
我有一个由父 POM 和几个子模块组成的 Maven 项目。它在 Intellij 中编译和运行良好(我假设它使用 javac 而不是 Maven)。 当我运行 maven clean install
所以我刚开始使用 d3.js,但我一直收到 JavaScript 错误,我不知道为什么。我刚刚用 svg 创建了三个圆圈,想用 d3 选择它们。这是我的代码:
Objective C 引入了一种称为 ARC 的技术,以将开发人员从内存管理的负担中解放出来。听起来不错,如果g++也有这个功能,我想C++开发者会很高兴的。 ARC allows you to p
在 package.json 添加 "font-awesome": "^4.7.0" 执行 npm install 在 main.js 引入
为什么 WSDL 引入 wsdl:message?和消息部分? 与在操作参数(输入、输出、故障)中直接使用 XSD 相比,他们可以带来什么优势? 它们(带有 wsdl 消息部分的 wsdl 消息)如何
I already read doc here : https://github.com/laravel/framework/pull/25997 我想知道的是使用 withCount()我们只是加载
我已经为此苦苦挣扎了一段时间,但不太明白发生了什么。我有一个包含 Sides(通常是 2 个)的 Card 实体 - 并且 Cards 和 Sides 都有一个 Stage。我正在使用 EF Code
下面的 swiftUI 代码在 iOS13 上运行良好,但是在使用 iOS14 进行测试时,我在尝试显示模式表时遇到了由强制解包选项引起的 fatal error 。据我所知,工作表不应该尝试为 se
出于个人原因,我需要记忆一下 jsp 上的一些事情 :) 我有一个简单的登录页面: Login First name:
据我了解,PYTHONCASEOK 选项允许通过不区分大小写的匹配来导入模块。但是,由于 python 中的几乎所有内容都区分大小写,为什么它必须启用此选项以实现更惰性的写入。 还有什么介绍的理由吗?
全新的早午餐(和 bower )。我通过 bower 安装了 Bootstrap,我有以下早午餐配置文件: exports.config = # See http://brunch.io/#doc
我是一名优秀的程序员,十分优秀!