为什么在 TypeScript 中禁止实现具有非公共成员的类?

Jes*_*pez 5 typescript

有以下课程:

class Trait {
    publicMethod() {
        this.privateMethod();
        // do something more
    }

    private privateMethod() {
        // do something usefull
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我尝试通过以下方式实现它:

class MyClass implements Trait {
    publicMethod() {}
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

MyClass 错误地实现了接口 Trait。类型“MyClass”中缺少属性“privateMethod”

如果我尝试通过以下方式实现它:

class MyClass implements Trait {
    publicMethod() {}

    private privateMethod() {}
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

MyClass 错误地实现了接口 Trait。类型具有私有属性“privateMethod”的单独声明

如果我尝试以下操作:

class MyClass implements Trait {
    publicMethod() {}

    public privateMethod() {}
}
Run Code Online (Sandbox Code Playgroud)

我收到错误:

MyClass 错误地实现了接口 Trait。属性“privateMethod”在“Trait”类型中是私有的,但在“MyClass”类型中不是私有的

受保护的方法以及私有和受保护的属性也会发生同样的情况。因此,为了能够实现该类,该类的所有成员都必须是公共的。

为什么在 TypeScript 中禁止实现具有非公共成员的类?

编辑:好的,实现将类视为接口,并且因为接口不能具有私有成员,所以您不能实现具有非公共成员的类。但为什么不忽略非公共成员呢?

提出这个问题是因为我想应用 mixin 来重用代码。另一种选择是组合,但是有一个使用 mixin 和非公共成员的解决方案。

这是解决方案:

function applyMixins(derivedCtor: any, baseCtors: any[]) {
    baseCtors.forEach(baseCtor => {
        Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
            derivedCtor.prototype[name] = baseCtor.prototype[name];
        })
    });
}

interface ITrait {
    publicMethod();
}

class Trait implements ITrait {
    publicMethod() {
        this.privateMethod();
        // do something more
    }

    private privateMethod() {
        // do something usefull
    }
}

class MyClass implements ITrait {
    publicMethod() {}
}

applyMixins(MyClass, [Trait]);
Run Code Online (Sandbox Code Playgroud)

Mar*_*cka 4

本质上,关键字implementsTrait类视为接口,并且接口不能具有私有方法。

请参阅此处 mixins 和私有方法背后的基本原理:https ://github.com/Microsoft/TypeScript/issues/5070

编辑:很容易发现 mixins 中私有方法的第一个问题以及它们不受支持的原因。如果两个特征具有同名的私有方法怎么办?它们必须不能互相影响,但这并不容易做到(考虑instance['my' + 'method']()符号)。

来自CodePlex 上的 TypeScript 文档

在上面你可能注意到的第一件事是,我们没有使用“扩展”,而是使用“实现”。这将类视为接口,并且仅使用 Disposable 和 Activatable 背后的类型而不是实现。这意味着我们必须在课堂上提供实现。不过,这正是我们想通过使用 mixin 来避免的。