I tried to define the function of a mixin()
type decorator mixin()
as shown below,
type Constructor<T> = new(...args: any[]) => T;
function mixin<T>(MixIn: Constructor<T>) {
return function decorator<U>(Base: Constructor<U>) : Constructor<T & U> {
Object.getOwnPropertyNames(MixIn.prototype).forEach(name => {
Base.prototype[name] = MixIn.prototype[name];
});
return Base as Constructor<T & U>;
}
}
And used it as follows:
class MixInClass {
mixinMethod() {console.log('mixin method is called')}
}
@mixin(MixInClass)
class Base1 {
baseMethod1() { }
}
const m1 = new Base1();
m1.baseMethod1();
m1.mixinMethod();
Then the compiler said that it m1
does not have a member 'mixinMethod'
.
And the generated code is as follows:
var Base1 = (function () {
function Base1() {
}
Base1.prototype.baseMethod1 = function () { };
Base1 = __decorate([
mixin(MixInClass)
], Base1);
return Base1;
}());
It seems that the decorator mixin
was applied correctly.
So, in my understanding, a type m1
is defined as Base1 & MixIn
. But the compiler says it is simple Base1
.
I used tsc 2.6.2
and compiled these codes with a flag --experimentalDecorators
.
Why can't the compiler recognize the type as I expected?
Based on @jcalz's answer, I changed my code as follows:
type Constructor<T> = new(...args: any[]) => T
function mixin<T1, T2>(MixIns: [Constructor<T1>, Constructor<T2>]): Constructor<T1&T2>;
function mixin(MixIns) {
class Class{ };
for (const MixIn of MixIns) {
Object.getOwnPropertyNames(MixIn.prototype).forEach(name => {
Class.prototype[name] = MixIn.prototype[name];
});
}
return Class;
}
class MixInClass1 {
mixinMethod1() {}
}
class MixInClass2 {
mixinMethod2() {}
}
class Base extends mixin([MixInClass1, MixInClass2]) {
baseMethod() { }
}
const x = new Base();
x.baseMethod();
x.mixinMethod1();
x.mixinMethod2();
x.mixinMethod3();
. mixin
mixin .
, ,
function mixin<T1>(MixIns: [Constructor<T1>]): Constructor<T1>;
function mixin<T1, T2>(MixIns: [Constructor<T1>, Constructor<T2>]): Constructor<T1&T2>;
function mixin<T1, T2, T3>(MixIns: [Constructor<T1>, Constructor<T2>, Constructor<T3>]): Constructor<T1&T2&T3>;
. ? , variadic-kind ?