在本教程中,你将学习 TypeScript 中的类型保护。
使用 条件代码块 限定变量类型的范围,达到类型保护的目的。
看看下面的例子:
type alphanumeric = string | number;
function add(a: alphanumeric, b: alphanumeric) {
if (typeof a === 'number' && typeof b === 'number') {
return a + b;
}
if (typeof a === 'string' && typeof b === 'string') {
return a.concat(b);
}
throw new Error(
'Invalid arguments. Both arguments must be either numbers or strings.',
);
}
它是这样工作的:
在这个例子中,TypeScript 知道如何在条件代码块中使用 typeof
操作符。
在下面的 if 语句中,TypeScript 认为 a
和 b
变量都是数字类型:
if (typeof a === 'number' && typeof b === 'number') {
return a + b;
}
类似地,在下面的 if
语句中,TypeScript 将 a
和 b
变量作为字符串来处理,因此,可以把它们拼接成一个字符串:
if (typeof a === 'string' && typeof b === 'string') {
return a.concat(b);
}
与 typeof
操作符类似,TypeScript 也知道如何使用 instanceof
操作符,如下所示:
class Customer {
isCreditAllowed(): boolean {
// ...
return true;
}
}
class Supplier {
isInShortList(): boolean {
// ...
return true;
}
}
type BusinessPartner = Customer | Supplier;
function signContract(partner: BusinessPartner): string {
let message: string;
if (partner instanceof Customer) {
message = partner.isCreditAllowed()
? 'Sign a new contract with the customer'
: 'Credit issue';
}
if (partner instanceof Supplier) {
message = partner.isInShortList()
? 'Sign a new contract the supplier'
: 'Need to evaluate further';
}
return message;
}
它这样何工作的:
Customer
和 Supplier
两个类;BusinessPartner
的类型,它是Customer
和 Supplier
的联合类型;signContract()
函数,它接受一个类型为 BusinessPartner
的参数;partner
是否为 Customer
或者 Supplier
类的实例,然后进行对应的逻辑处理。在下面的 if
代码块中,TypeScript 通过 instanceof
操作符知道 partner
是 Customer
类型的一个实例:
if (partner instanceof Customer) {
message = partner.isCreditAllowed()
? 'Sign a new contract with the customer'
: 'Credit issue';
}
同样的方式,在下面的 if
代码块中,TypeScript 知道 partner
是 Supplier
类型的一个实例:
if (partner instanceof Supplier) {
message = partner.isInShortList()
? 'Sign a new contract with the supplier'
: 'Need to evaluate further';
}
当 if
语句限定了一种类型,TypeScript 知道在 else
语句中会是另外一种类型,如下所示:
function signContract(partner: BusinessPartner): string {
let message: string;
if (partner instanceof Customer) {
message = partner.isCreditAllowed()
? 'Sign a new contract with the customer'
: 'Credit issue';
} else {
// must be Supplier
message = partner.isInShortList()
? 'Sign a new contract with the supplier'
: 'Need to evaluate further';
}
return message;
}
in
操作符通过判断对象上是否存在某个属性来进行安全检查,也可以将它用作类型保护,如下所示:
function signContract(partner: BusinessPartner): string {
let message: string;
if ('isCreditAllowed' in partner) {
message = partner.isCreditAllowed()
? 'Sign a new contract with the customer'
: 'Credit issue';
} else {
// must be Supplier
message = partner.isInShortList()
? 'Sign a new contract the supplier '
: 'Need to evaluate further';
}
return message;
}
用户自定义的类型保护允许你使用函数的时候定义类型保护或者帮助 TypeScript 推断类型。用户自定义的类型保护函数是一个返回 arg is aType
判断的函数,如下所示:
function isCustomer(partner: any): partner is Customer {
return partner instanceof Customer;
}
在这个例子中,isCustomer()
是一个用户自定义的类型保护函数,可以按照下面的例子来使用它:
function signContract(partner: BusinessPartner): string {
let message: string;
if (isCustomer(partner)) {
message = partner.isCreditAllowed()
? 'Sign a new contract with the customer'
: 'Credit issue';
} else {
message = partner.isInShortList()
? 'Sign a new contract with the supplier'
: 'Need to evaluate further';
}
return message;
}
typeof
和 instanceof
操作符在条件语句中实现类型保护。