TypeScript:ReturnType中this['initialize']与typeof this.initialize的差异
为什么
ReturnType<this['initialize']>与ReturnType<typeof this.initialize>的类型推断结果不同? 我们的目标是在抽象类中推断initialize方法的返回类型,并将其应用到prop属性上,但两种写法的类型推断结果完全不同:
能正确推断子类返回类型的写法
以下代码中,prop会被正确推断为Child类型,调用子类方法不会报错:
class Base { method_1() {} } class Child extends Base { method_2() {} } abstract class AbstractClass { prop: ReturnType<this['initialize']> abstract initialize(): Base } class UserClass2 extends AbstractClass { initialize() { return new Child() } someMethod() { this.prop.method_1() // 正常,无TS错误 this.prop.method_2() // 正常,无TS错误 } }
只能推断父类返回类型的写法
以下代码中,prop始终被推断为Base类型,调用子类独有的method_2会报错:
class Base { method_1() {} } class Child extends Base { method_2() {} } abstract class AbstractClass { prop: ReturnType<typeof this.initialize> abstract initialize(): Base } class UserClass2 extends AbstractClass { initialize() { return new Child() } someMethod() { this.prop.method_1() // 正常,无TS错误 this.prop.method_2() // 报错! } }
两者的核心差异
这两种写法的本质区别在于TypeScript对this的处理逻辑:
this['initialize']:这里的this是「多态this类型」,它会保留子类的类型信息。当子类重写initialize方法后,this['initialize']会动态指向子类中重写的方法,因此ReturnType能正确获取到子类方法的返回类型Child。typeof this.initialize:typeof操作符会在抽象类的上下文里直接解析this.initialize的类型,此时this被认定为AbstractClass类型,对应的initialize方法类型是抽象类中定义的() => Base,所以ReturnType只能得到Base,无法继承子类的重写信息。
简单来说,索引访问语法this['key']会保留多态this的动态特性,而typeof this.key会在当前类层面静态解析类型,忽略子类的重写逻辑。
内容的提问来源于stack exchange,提问作者Khanon
相关产品推荐
相关产品推荐

