Type Guards
类型守卫是您通过代码影响代码流分析的功能。
TypeScript 使用现存的 JavaScript 在运行时验证对象的行为来进行代码流分析。
本文假定您已阅读 example:code-flow
为了展示这些例子,我们会创建一些类。
这是用来处理互联网或电话订单的系统。
// 我们可以使用 'in' 操作符来检查某个特定的键存在在对象上,
以缩小并集类型的范围 ('in' 是 JavaScript中用来检查对象上键是否存在的操作符)。
interface Order {
address: string;
}
interface TelephoneOrder extends Order {
callerNumber: string;
}
interface InternetOrder extends Order {
email: string;
}
// 然后定义一个可能是两种订单子类型之一或 undefined 的类型。
type PossibleOrders = TelephoneOrder | InternetOrder | undefined;
// 创建一个函数,返回 PossibleOrders 类型。
declare function getOrder(): PossibleOrders;
const possibleOrder = getOrder();
// 你可以使用 JavaScript 中 'typeof' 操作符来缩小您的并集类型。
它只对于 JavaScript 中的基本类型起作用(例如字符串,对象,数组等)。
if ("email" in possibleOrder) {
const mustBeInternetOrder = possibleOrder;
}
// 如果您有符合接口的类,可以使用 JavaScript 中 'instanceof' 操作符来检查。
class TelephoneOrderClass {
address: string;
callerNumber: string;
}
if (possibleOrder instanceof TelephoneOrderClass) {
const mustBeTelephoneOrder = possibleOrder;
}
// 你可以在这里看到全部 typeof 的可能的值:
https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/typeof
使用 JavaScript 操作符仅仅可以帮助您实现一部分功能,
当您希望检查自己定义的类型时,您可以使用类型谓词函数。
类型谓词函数是一个当返回 true 时,会给代码流分析提供一些额外信息的函数。
要使用 PossibleOrders 类型,我们可以用两个类型守卫
来声明 possibleOrder 究竟是哪个类型:
if (typeof possibleOrder === "undefined") {
const definitelyNotAnOder = possibleOrder;
}
// 你可以在这里获得更多关于代码流分析的信息:
- example:code-flow
- example:type-guards
- example:discriminate-types
function isAnInternetOrder(order: PossibleOrders): order is InternetOrder {
return order && "email" in order;
}
function isATelephoneOrder(order: PossibleOrders): order is TelephoneOrder {
return order && "calledNumber" in order;
}
// 现在我们可以使用这些函数在 if 语句中缩小 possibleOrder 的可能的类型:
if (isAnInternetOrder(possibleOrder)) {
console.log("Order received via email:", possibleOrder.email);
}
if (isATelephoneOrder(possibleOrder)) {
console.log("Order received via phone:", possibleOrder.callerNumber);
}