You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 12:15:04