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

TypeScript中抽象类方法能否引用实现类的类型?

解决方案:实现静态方法的多态类型推断

你的问题核心在于TypeScript对静态方法中this的类型推断默认绑定父类,无法自动关联子类重写后的静态方法返回类型。以下两种方案可以解决这个问题:

方案1:泛型类 + this类型约束

通过给抽象类添加泛型参数,明确绑定子类differentFunc的返回类型,同时用this类型约束确保调用上下文是子类:

interface MyStuff {
    [name: string]: {someParam: string}
};

type Something<T> = {
    thing: T;
}

// 泛型T代表子类differentFunc的返回类型
abstract class Thingydoo<T extends MyStuff> {
    // 用this约束当前类必须包含返回类型为T的differentFunc方法
    static testWithTypeParam<T extends MyStuff>(this: { differentFunc: () => T }, thing: T): Something<T> {
        console.log("hi! this is a " + this.name);
        return {thing: thing};
    }

    abstract static differentFunc(): T;
}

class Thingymabob extends Thingydoo<{beans: {someParam: string}}> {
    static differentFunc(): {beans: {someParam: string}} {
        return {beans: {someParam: "test"}};
    }

    static feedMeBeans(beansContainer: {beans: {someParam: string}}) {
        console.log(beansContainer.beans.someParam);
    }
}

let something = Thingymabob.testWithTypeParam({beans: {someParam: "test3"}});
// TypeScript现在能正确推断something.thing的类型,编译通过
Thingymabob.feedMeBeans(something.thing);

这种方式类型约束明确,适合需要强制子类遵循特定返回类型规范的场景。

方案2:利用infer提取子类返回类型

不需要修改类的泛型定义,直接在静态方法中通过infer关键字动态提取子类differentFunc的返回类型:

interface MyStuff {
    [name: string]: {someParam: string}
};

type Something<T> = {
    thing: T;
}

abstract class Thingydoo {
    // 通过infer R提取子类differentFunc的返回类型
    static testWithTypeParam(this: typeof Thingydoo & { differentFunc: () => infer R }, thing: R): Something<R> {
        console.log("hi! this is a " + this.name);
        return {thing: thing};
    }

    static differentFunc(): MyStuff {
        return {};
    }
}

class Thingymabob extends Thingydoo {
    static differentFunc(): {beans: {someParam: string}} {
        return {beans: {someParam: "test"}};
    }

    static feedMeBeans(beansContainer: {beans: {someParam: string}}) {
        console.log(beansContainer.beans.someParam);
    }
}

let something = Thingymabob.testWithTypeParam({beans: {someParam: "test3"}});
Thingymabob.feedMeBeans(something.thing); // 编译通过

这种方案更灵活,无需修改父类的泛型结构,适合快速适配现有代码。

内容的提问来源于stack exchange,提问作者Curtis Parfitt-Ford

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 14:57:40