Typescript 3.7引入了一些破解功能,如可选链和nullish凝聚。TypeScript 3.7还引入了另一个有用的功能,这就是断言签名。在这篇文章中,我们将了解什么是断言签名以及我们可以在哪里使用它们。
带有类型谓词的类型保护
假设我们对一个字段可以拥有的各种编辑元素有以下类型:
type Editor =
| HTMLInputElement
| HTMLSelectElement;
所以,编辑元素可以是一个input 元素或select 元素。
我们需要实现一个函数,如果编辑元素是一个复选框,就可以得到这个值。在TypeScript 3.7之前,我们可以用一个类型谓词来完成这个任务:
function getCheckboxValue(editor: Editor) {
if (isCheckbox(editor)) {
// type of editor narrowed to HTMLInputElement
return editor.checked;
}
throw new Error("editor is not a checkbox");
}
function isCheckbox(
editor: Editor
): editor is HTMLInputElement {
return "checked" in editor;
}
getCheckboxValue 函数接收了一个名为editor 的参数,类型为Editor 。在if 条件里面,editor 参数的类型已经被缩小到HTMLInputElement 。这意味着TypeScript对editor 中的checked 属性感到满意。
在这里,isCheckbox 类型谓词被用来将editor 的类型缩小到HTMLInputElement 。返回类型注释,editor is HTMLInputElement 告诉 TypeScript,当函数返回true 时,editor 的类型可以被缩小到HTMLInputElement 。
使用断言签名的类型保护
断言签名是实现类型保护的另一种方法。让我们试一试吧:
function getCheckboxValue(editor: Editor) {
assertIsCheckbox(editor); // type of editor narrowed to HTMLInputElement
return editor.checked;
}
function assertIsCheckbox(
editor: Editor
): asserts editor is HTMLInputElement { if (!("checked" in editor)) {
throw new Error("Not a checkbox");
}
}
断言签名在assertIsCheckbox 函数中,在返回类型注释中。在我们的例子中,这是asserts editor is HTMLInputElement ,其结果是在这个函数被返回后,editor 被缩小为HTMLInputElement 。
使用一般断言函数的类型保护
我们可以实现一个包含断言签名的一般assert 函数,如下所示:
function assert(
condition: any,
msg?: string
): asserts condition { if (!condition) {
throw new Error(msg);
}
}
这告诉TypeScript,如果函数返回,无论传入condition 参数的是什么,都必须是true (因为否则,它将抛出一个错误)。
我们可以在getCheckboxValue 函数中使用它,如下所示:
function getCheckboxValue(editor: Editor) {
assert(
"checked" in editor,
"editor is not a checkbox"
);
// type of editor narrowed to HTMLInputElement
return editor.checked;
}
包裹起来
断言签名是实现类型保护的一种方式,用于缩小变量的类型。可以说,它比使用类型谓词更接近于标准的JavaScript结构。