摘要:在本教程中,您将了解 TypeScript 的 never 类型,它用于表示永远不会发生的值。
TypeScript never 类型的介绍
在 TypeScript 中,类型就像一组值。例如,number 类型包含数字 1、2、3 等。string 类型包含字符串,例如 'Hi'、'Hello' 等。null 类型包含单个值,即 null。
never 类型是一种不包含任何值的类型。它就像一个空集。
由于 never 类型不包含任何值,因此您无法将值赋给具有 never 类型的变量。
例如,以下操作将导致错误
let empty: never = 'hello';Code language: JavaScript (javascript)TypeScript 编译器会发出以下错误
Type 'string' is not assignable to type 'never'Code language: JavaScript (javascript)那么,我们为什么首先需要 never 类型呢?
由于 never 类型的值为零,因此您可以使用它来表示类型系统中的不可能情况。
例如,您可能有一个 交叉类型,它可以同时是字符串和数字,这是不可能的
type Alphanumeric = string & number; // neverCode language: JavaScript (javascript)因此,TypeScript 编译器将 Alphanumeric 的类型推断为 never。
这是因为 string 和 number 是互斥的。换句话说,一个值不能同时是 string 和 number。
通常,您使用 never 类型来表示永不将控制权返回给调用者的函数的返回类型。例如,一个总是抛出错误的函数
function raiseError(message: string): never {
throw new Error(message);
}Code language: TypeScript (typescript)请不要将其与返回 void 但仍将控制权返回给调用者的函数混淆。
如果您的函数包含无限循环,则其返回类型应为 never。例如
function forever(): never {
while (true) {}
}Code language: TypeScript (typescript)在此示例中,forever() 函数的返回类型的类型为 never。
TypeScript never 示例
让我们举一个使用 never 类型的例子
type Role = 'admin' | 'user';
const authorize = (role: Role): string => {
switch (role) {
case 'admin':
return 'You can do anything';
case 'user':
return 'You can do something';
default:
// never reach here util we add a new role
const _unreachable: never = role;
throw new Error(`Invalid role: ${_unreachable}`);
}
};
console.log(authorize('admin'));
Code language: JavaScript (javascript)它是如何工作的。
步骤 1. 定义一个类型 Role,它可以是字符串 'admin' 或 'user'
type Role = 'admin' | 'user';Code language: JavaScript (javascript)步骤 2. 创建 authorize() 函数,该函数接受 Role 类型的变量并返回一个字符串
const authorize = (role: Role): string => {
switch (role) {
case 'admin':
return 'You can do anything';
case 'user':
return 'You can do something';
default:
// never reach here util we add a new role
const _unreachable: never = role;
throw new Error(`Invalid role: ${_unreachable}`);
}
};Code language: JavaScript (javascript)它是如何工作的。
首先,使用 switch 语句在角色为 admin 或 user 时返回相应的字符串。
其次,定义一个名为 _unreachable 的变量,其类型为 never,并将 role 赋给它。此外,在 default 分支中抛出错误,因为执行永远不会到达 default 分支。
我们为什么要处理 default 案例?
原因是,如果我们向 Role 类型添加新值并忘记添加处理新角色的逻辑,TypeScript 将发出错误
type Role = 'admin' | 'user' | 'guest';Code language: JavaScript (javascript)在这种情况下,我们将 'guest' 添加到 Role 类型。
TypeScript 会发出以下错误
Type 'string' is not assignable to type 'never'.ts(2322)Code language: JavaScript (javascript)这是因为 default 分支中角色的值现在变为字符串 'guest',并且您无法将字符串值赋给类型为 never 的变量。
要解决此问题,您需要创建一个新的 case 分支来处理新角色
const authorize = (role: Role): string => {
switch (role) {
case 'admin':
return 'You can do anything';
case 'user':
return 'You can do something';
case 'guest':
return 'You can do nothing';
default:
// never reach here util we add a new role
const _unreachable: never = role;
throw new Error(`Invalid role: ${_unreachable}`);
}
};Code language: JavaScript (javascript)为了使其更简洁,我们可以定义一个返回类型为 never 的函数,并在 default 分支中使用它
type Role = 'admin' | 'user' | 'guest';
const unknownRole = (role: never): never => {
throw new Error(`Invalid role: ${role}`);
};
const authorize = (role: Role): string => {
switch (role) {
case 'admin':
return 'You can do anything';
case 'user':
return 'You can do something';
case 'guest':
return 'You can do nothing';
default:
// never reach here util we add a new role
return unknownRole(role);
}
};
console.log(authorize('admin'));
Code language: TypeScript (typescript)总结
- 使用
never类型,它不包含任何值,表示类型系统中的不可能情况。