Consider the following scenario:
class Trait {
publicMethod() {
this.privateMethod();
// do something more
}
private privateMethod() {
// perform a useful action
}
}
When attempting to implement it like this:
class MyClass implements Trait {
publicMethod() {}
}
An error is thrown stating:
MyClass improperly implements interface Trait. Property 'privateMethod' is missing in type 'MyClass'
If implemented like this:
class MyClass implements Trait {
publicMethod() {}
private privateMethod() {}
}
The error received is:
MyClass improperly implements interface Trait. Types have separate declarations of a private property 'privateMethod'
Attempting the following approach:
class MyClass implements Trait {
publicMethod() {}
public privateMethod() {}
}
An error is triggered:
MyClass improperly implements interface Trait. Property 'privateMethod' is private in type 'Trait' but not in type 'MyClass'
This limitation also applies to protected methods, private, and protected properties. It appears that all members of a class must be public in order to implement it successfully.
Why does TypeScript prohibit implementing a class with non-public members?
EDIT: The issue arises because when using `implements`, classes are treated as interfaces and interfaces cannot contain private members. One solution could be to simply ignore non-public members.
This question emerged from a desire to utilize mixins for code reuse. Although composition is an option, there exists a workaround using mixins and non-public members.
Here is a workaround solution:
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() {
// perform a useful action
}
}
class MyClass implements ITrait {
publicMethod() {}
}
applyMixins(MyClass, [Trait]);