TypeScript 类型保护
摘要:在本教程中,你将了解 TypeScript 中的类型保护来缩小变量的类型范围。
类型防护允许您缩小条件块中变量的类型范围。
typeof
让我们看一下下面的例子:
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.');
}
怎么运行的:
- 首先,定义可以保存字符串或数字的
alphanumberic
类型。 - 接下来,声明一个函数,将两个字母数字类型的变量
a
和b
相加。 - 然后,使用
typeof
运算符检查两种类型的参数是否都是数字。 如果是,则使用+
运算符计算参数之和。 - 之后,使用
typeof
运算符检查两种类型的参数是否都是字符串。 如果是,则连接两个参数。 - 最后,如果参数既不是数字也不是字符串,则抛出错误。
在此示例中,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);
}
instanceof
与 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
和Supply
的联合类型。 - 第三,声明一个函数
signContract()
,它接受BusinessPartner
类型的参数。 - 最后,检查合作伙伴是否是
Customer
或Supplier
的实例,然后提供各自的逻辑。
在下面的 if
块中,由于 instanceof
运算符,TypeScript 知道合作伙伴是 Customer
类型的实例:
if (partner instanceof Customer) {
message = partner.isCreditAllowed() ? 'Sign a new contract with the customer' : 'Credit issue';
}
同样,TypeScript 知道合作伙伴是以下 if
块内的 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
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
运算符在条件块中实现类型保护