TypeScript如何通过getter或字符串比较实现类型收窄替代instanceof?
TypeScript 非 instanceof 类型收窄解决方案
TS 原生支持你要的两种收窄方式,只需要对现有代码做少量改造即可:
基于 type 字符串比较的收窄
这个是TS内置的可辨识联合特性,只要用一个公共的字面量类型字段作为辨识标识,TS会自动根据该字段的判断逻辑收窄对象类型,你的原有代码基本已经符合要求,只需要把基类的 type 调整为非空的抽象属性(避免基类实例干扰类型判断,可选操作):
export abstract class Token { // 强制子类实现具体的type字面量类型 abstract type: 'TokenContainer'|'TokenPrimitive'; foo0(){} } export class TokenContainer extends Token { type: 'TokenContainer' = 'TokenContainer'; foo1(){} } export class TokenPrimitive extends Token { type: 'TokenPrimitive' = 'TokenPrimitive'; foo2(){} } let test!:Token; // 该判断已经可以正常生效,test被自动收窄为TokenContainer类型 if(test.type === 'TokenContainer' ){ test.foo1() }
基于 getter 属性的收窄
只需要给 getter 的返回值加上类型谓词声明,告诉 TS 当该 getter 返回 true 时,当前实例对应的类型即可:
export abstract class Token { abstract type: 'TokenContainer'|'TokenPrimitive'; // 类型谓词:返回true时,当前实例为TokenContainer类型 get isContainer(): this is TokenContainer { return this.type === 'TokenContainer' } get isPrimitive(): this is TokenPrimitive { return this.type === 'TokenPrimitive' } foo0(){} } export class TokenContainer extends Token { type: 'TokenContainer' = 'TokenContainer'; foo1(){} } export class TokenPrimitive extends Token { type: 'TokenPrimitive' = 'TokenPrimitive'; foo2(){} } let test!:Token; // 该判断现在可以正常生效 if(test.isContainer){ test.foo1() }
两种方案都完全不需要用到 instanceof 语法,改造成本极低。
内容的提问来源于stack exchange,提问作者jon
相关产品推荐
相关产品推荐

