/
mixin.ts
93 lines (78 loc) · 2.12 KB
/
mixin.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// Note: This is a copy of the mixin test case for the converter.
/**
* Any function
*/
export type AnyFunction<A = any> = (...input: any[]) => A;
/**
* Any constructor function
*/
export type AnyConstructor<A = object> = new (...input: any[]) => A;
/**
* Mixin type helper
*/
export type Mixin<T extends AnyFunction> = InstanceType<ReturnType<T>>;
/**
* Base class
*/
export class Base {
baseProperty = "init";
baseMethod(): number {
return 42;
}
}
/**
* The "mixin function" of the Mixin1
*/
export const Mixin1Func = <T extends AnyConstructor<Base>>(base: T) =>
/**
* Internal class of the Mixin1
*/
class Mixin1Class extends base {
property1 = "init";
method1(arg: Mixin1Type[]): Mixin1Type[] {
return [...arg, this];
}
};
/**
* The "instance type" of the Mixin1 using the interface notation (supports recursive type definition)
*/
export interface Mixin1Type extends Mixin<typeof Mixin1Func> {}
/**
* The "mixin function" of the Mixin2
*/
export const Mixin2 = <T extends AnyConstructor<Mixin1Type & Base>>(base: T) =>
/**
* Internal class of the Mixin2
*/
class Mixin2 extends base {
property2 = "init";
method2(arg: Mixin2Type): Mixin2Type {
return arg;
}
};
/**
* The "instance type" of the Mixin2 using the interface notation (supports recursive type definition)
*/
export interface Mixin2Type extends Mixin<typeof Mixin2> {}
/**
* The "mixin function" of the Mixin3
*/
export const Mixin3 = <T extends AnyConstructor<object>>(base: T) =>
/**
* Internal class of the Mixin3
*/
class Mixin3 extends base {};
/**
* The "instance type" of the Mixin3 using the regular type notation (does not work well for recursive type definition)
* Is not well supported by the TypeDoc
*/
export type Mixin3 = Mixin<typeof Mixin3>;
/**
* Class that inherits from Base and consumes Mixin1 and Mixin2, in order.
*/
export class SomeClassWithMixin extends Mixin2(Mixin1Func(Base)) {
classWithMixinProperty = "init";
classWithMixinMethod(): string {
return "42";
}
}