/*保证typescript可以正确计算类型*/
export function extend<T, U>(target: Type<T>, source1: Type<U>): Type<T & U>;
export function extend<T, U, V>(
target: Type<T>,
source1: Type<U>,
source2: Type<V>
): Type<T & U & V>;
export function extend<T, U, V, W>(
target: Type<T>,
source1: Type<U>,
source2: Type<V>,
source3: Type<W>
): Type<T & U & V & W>;
export function extend<T, U, V, W, X>(
target: Type<T>,
source1: Type<U>,
source2: Type<V>,
source3: Type<W>,
source4: Type<W>
): Type<T & U & V & W & X>;
/*结束*/
/*功能*/
export function extend(target: Type<any>, ...sources: Type<any>[]): Type<any> {
return extend2(target)(...sources.reverse());
}
function extend2(target: Type<any>) {
return (...sources: Type<any>[]): Type<any> => {
let targetPrototype = target.prototype;
// 继承
(function() {
// 创建一个干净的实例
function beget() {
var F = function() {
// sources属性处理
sources.map(source => source.call(this));
};
// sources处理
assign(F.prototype, ...sources.map(source => source.prototype));
return new F();
}
let prototype = beget();
prototype.constructor = target;
// 继承
target.prototype = prototype;
// 原来的方法
assign(target.prototype, targetPrototype);
})();
return target as any;
};
}
/*结束*/
测试
import { expect } from "chai";
import { extend } from "./extend";
export class A {
title: string = "a";
run() {
return "a";
}
}
export class B {
title: string = "b";
demo: string = "demo";
add() {
return "b";
}
}
export class D {
title: string = "d";
console() {
return "d";
}
}
let C = extend(A, B, D);
const c = new C();
describe("extend", () => {
it("c.demo", () => {
expect(c.demo).equal("demo");
});
it("c.add", () => {
expect(c.add()).equal("b");
});
it("c.add", () => {
expect(c.run()).equal("a");
});
it("c.add", () => {
expect(c.console()).equal("d");
});
});