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

TypeScript编译器未检测到混入抽象类未实现的getter问题

问题:TypeScript未检测到未实现的抽象属性interface

根据@artur-grzesiak的评论,我们修改了示例,简化版本移除了命名不当的interface方法,但仍预期编译器会对未实现的interface属性抛出错误,然而并未出现。

type GConstructor<T = {}> = abstract new (...args: any[]) => T;

// 原始对象接口
interface IBaseDataObject {
    readonly id: string;
}
// 名称模式接口
interface Name {
    name: string;
}

// 类必须实现的接口
interface BaseDataObjectInterface<T extends IBaseDataObject> {
    readonly id: string;
    readonly interface: T;
}

abstract class AbstractBaseObject<T extends IBaseDataObject> {
    readonly id: string;
    abstract readonly interface: T

    constructor(
        iBaseDataObject: T
    ) {
        this.id = iBaseDataObject.id;
    }
}

type AbstractBaseObjectCtor<T extends IBaseDataObject> = GConstructor<AbstractBaseObject<T>>;

// 国家相关的接口、类定义
interface ICountry extends IBaseDataObject, Name {}

function NameAbstractMixin<TBase extends AbstractBaseObjectCtor<T>, T extends IBaseDataObject & Name>(Base: TBase) {
    abstract class NamedBase extends Base implements Name {
        readonly name: string;

        constructor(...args: any[]) {
            super(...args)
            this.name = args[0].name;
        }

    }
    return NamedBase;
}


class Country extends NameAbstractMixin(AbstractBaseObject<ICountry>) implements BaseDataObjectInterface<ICountry> {
    // get interface(): ICountry {
    //     return {
    //         id : "hello",
    //         name: "France",
    //     }
    // }
}

问题详情

Country类继承了通过混入创建的抽象类(基类为AbstractBaseObject<ICountry>),AbstractBaseObject声明了抽象属性interface,同时Country类还实现了要求该属性的BaseDataObjectInterface<ICountry>,但TypeScript编译器并未检测到该属性未实现的错误,请问是否遗漏了什么?


原因与解决方案

这是TypeScript对JavaScript保留字的特殊处理导致的问题:

  1. interface是JavaScript的保留字,虽然TypeScript允许在特定场景下使用保留字作为成员名称,但编译器对这类名称的抽象属性检查存在漏洞,无法正常触发未实现的错误提示。
  2. 另外,当类继承抽象类时,编译器会默认认为抽象类的抽象成员已经满足了接口的要求,不会再强制子类去实现——但如果成员名称是保留字,这个检查逻辑会失效得更明显。

解决办法:

  • 直接修改属性名称,避免使用保留字,比如改成dataInterface:
    // 修改接口
    interface BaseDataObjectInterface<T extends IBaseDataObject> {
        readonly id: string;
        readonly dataInterface: T;
    }
    
    // 修改抽象类
    abstract class AbstractBaseObject<T extends IBaseDataObject> {
        readonly id: string;
        abstract readonly dataInterface: T;
    
        constructor(iBaseDataObject: T) {
            this.id = iBaseDataObject.id;
        }
    }
    
    // 此时Country类如果不实现dataInterface,编译器会正常报错
    
  • 如果一定要使用interface作为名称,可以用引号包裹("interface"),但这种写法会降低代码可读性,不推荐:
    abstract class AbstractBaseObject<T extends IBaseDataObject> {
        readonly id: string;
        abstract readonly "interface": T;
    }
    

内容的提问来源于stack exchange,提问作者viduvern

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 04:26:02