TypeScript 中的感叹号(非空断言)运算符

TypeScript 中的感叹号(非空断言)运算符

Exclamation Mark (non-null assertion) operator in TypeScript

感叹号(非空断言)运算符从表达式的类型中删除null
undefined

null
当我们知道 TypeScript 认为可能是或
undefined实际上不是的变量时使用它。

索引.ts
type Employee = { id: number; name: string; }; function getEmployeeName(emp?: Employee) { return emp!.name; // 👈️ use non-null assertion } // 👇️ "Bobby Hadz" console.log(getEmployeeName({ id: 1, name: 'Bobby Hadz' }));

感叹号
(非空断言)运算符从类型中
删除
null和。undefined

emp函数中的参数被标记为
可选
,这意味着它可以是 typeEmployee或 be undefined

通过在变量名后使用感叹号,我们从变量类型中删除了and 。 nullundefined

如果我们不使用非空断言运算符,我们将在尝试访问该属性时遇到错误name

索引.ts
type Employee = { id: number; name: string; }; function getEmployeeName(emp?: Employee) { // ⛔️ Error: Object is possibly 'undefined'.ts(2532) return emp.name; } // 👇️ "Frank" console.log(getEmployeeName({ id: 1, name: 'Frank' }));

参数emp可能是undefined,所以我们不能安全地访问它的属性,因为它可能会导致运行时错误。

感叹号运算符是一个类型断言

请务必注意感叹号运算符只是一个
类型断言

换句话说,它不会为您的程序添加任何类型安全。

它不
检查指定的变量是否不为 null
和 not
undefined

感叹号运算符在发出的 JavaScript 代码中被删除,因此它的唯一功能是从变量的类型中删除null和。undefined

当我们使用非空断言运算符时,我们有效地告诉 TypeScript 这个变量永远不会是nullorundefined并且不用担心它。

该操作产生一个with
removed
myVar!类型的值myVarnullundefined

使用非空断言运算符的代码示例与此使用简单类型断言的代码示例非常相似。

索引.ts
type Employee = { id: number; name: string; }; function getEmployeeName(emp?: Employee) { return (emp as Employee).name; // 👈️ type assertion } // 👇️ "Bobby Hadz" console.log(getEmployeeName({ id: 1, name: 'Bobby Hadz' }));

我们告诉 TypeScript 变量emp将是类型的Employee,不用担心它。

非空断言运算符最常用于当您必须解决第三方包的错误类型时,或者在我们拥有 TypeScript 无法知道的有关值类型的信息的任何其他情况下。

有时你不能确定变量不是nullandundefined

有时候,我们真的不能确定具体的变量会不会是
nullor undefined,而是需要访问它上面的一个属性。

在这种情况下,使用可选的链接 (?.) 运算符要安全得多。

索引.ts
type Employee = { id: number; name: string; }; function getEmployeeName(emp?: Employee) { return emp?.name; // 👈️ use optional chaining } // 👇️ "Bobby Hadz" console.log(getEmployeeName({ id: 1, name: 'Bobby Hadz' }));

如果左侧的值为空值(或),则可选链接(?.)运算符短路并返回undefinednullundefined

这就是为什么 TypeScript 允许我们使用它来访问name可能
empundefined.

如果变量是nullor undefined,则可选的链接运算符会短路而不会引发任何错误。

使用if语句作为类型保护

或者,您可以使用if充当
类型保护的语句。

索引.ts
type Employee = { id: number; name: string; }; function getEmployeeName(emp?: Employee) { if (emp) { // 👉️ emp is type Employee here return emp.name; } // 👉️ emp is type undefined here return 'Bobby Hadz'; } // 👇️ "Bobby Hadz" console.log(getEmployeeName({ id: 1, name: 'Bobby Hadz' }));

我们的if语句用作类型保护,因为 TypeScript 知道如果满足条件,则emp变量的类型为Employee

否则,该变量的类型是,undefined因为这是唯一可能的类型。