/*保證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;
};
}
/*結束*/
複製代碼
測試typescript
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");
});
});
複製代碼