摘要:在本教程中,您将学习 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.');
}
Code language: TypeScript (typescript)
工作原理
- 首先,定义
alphanumeric
类型,它可以保存字符串或数字。 - 接下来,声明一个函数,该函数将两个变量
a
和b
相加,它们的类型为alphanumeric
。 - 然后,使用
typeof
运算符检查两个参数的类型是否都是数字。如果是,则使用+
运算符计算参数的总和。 - 之后,使用
typeof
运算符检查两个参数的类型是否都是字符串。如果是,则连接两个参数。 - 最后,如果参数既不是数字也不是字符串,则抛出错误。
在这个示例中,TypeScript 了解typeof
运算符在条件块中的使用。在以下if
块中,TypeScript 意识到a
和b
是数字。
if (typeof a === 'number' && typeof b === 'number') {
return a + b;
}
Code language: TypeScript (typescript)
类似地,在以下if
块中,TypeScript 将a
和b
视为字符串,因此您可以将它们连接成一个
if (typeof a === 'string' && typeof b === 'string') {
return a.concat(b);
}
Code language: TypeScript (typescript)
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;
}
Code language: TypeScript (typescript)
工作原理
- 首先,声明
Customer
和Supplier
类。
其次,创建一个类型别名BusinessPartner
,它是Customer
和Supplier
的联合类型。 - 第三,声明一个函数
signContract()
,它接受一个类型为BusinessPartner
的参数。 - 最后,检查合作伙伴是否是
Customer
或Supplier
的实例,然后提供相应的逻辑。
在以下if
块中,由于instanceof
运算符,TypeScript 知道合作伙伴是Customer
类型的实例
if (partner instanceof Customer) {
message = partner.isCreditAllowed() ? 'Sign a new contract with the customer' : 'Credit issue';
}
Code language: TypeScript (typescript)
同样,TypeScript 知道合作伙伴是以下if
块中的Supplier
实例
if (partner instanceof Supplier) {
message = partner.isInShortList() ? 'Sign a new contract with the supplier' : 'Need to evaluate further';
}
Code language: TypeScript (typescript)
当 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;
}
Code language: TypeScript (typescript)
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;
}
Code language: TypeScript (typescript)
用户定义的类型守卫
用户定义的类型守卫允许您定义类型守卫或在使用函数时帮助 TypeScript 推断类型。
用户定义的类型守卫函数是一个函数,它只是返回arg is aType
。例如
function isCustomer(partner: any): partner is Customer {
return partner instanceof Customer;
}
Code language: TypeScript (typescript)
在这个示例中,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;
}
Code language: TypeScript (typescript)
总结
- 类型守卫在条件块中缩小了变量的类型范围。
- 使用
typeof
和instanceof
运算符在条件块中实现类型守卫
本教程是否有用?