@@ -13,9 +13,9 @@ type Constructor<T> = new (...args: any[]) => T;
13
13
* @author https://stackoverflow.com/users/2887218/jcalz
14
14
* @see https://stackoverflow.com/a/50375286/10325032
15
15
*/
16
- type UnionToIntersection < Union > = ( Union extends any
17
- ? ( argument : Union ) => void
18
- : never ) extends ( argument : infer Intersection ) => void // tslint:disable-line: no-unused
16
+ type UnionToIntersection < Union > = (
17
+ Union extends any ? ( argument : Union ) => void : never
18
+ ) extends ( argument : infer Intersection ) => void // tslint:disable-line: no-unused
19
19
? Intersection
20
20
: never ;
21
21
@@ -31,16 +31,25 @@ export class Base {
31
31
static plugins : TestPlugin [ ] = [ ] ;
32
32
static plugin <
33
33
S extends Constructor < any > & { plugins : any [ ] } ,
34
- T extends TestPlugin | TestPlugin [ ]
35
- > ( this : S , plugin : T ) {
34
+ T1 extends TestPlugin ,
35
+ T2 extends TestPlugin [ ]
36
+ > ( this : S , plugin : T1 , ...p2 : T2 ) {
36
37
const currentPlugins = this . plugins ;
38
+ let newPlugins : ( TestPlugin | undefined ) [ ] = [
39
+ ...( plugin instanceof Array
40
+ ? ( plugin as TestPlugin [ ] )
41
+ : [ plugin as TestPlugin ] ) ,
42
+ ...p2 ,
43
+ ] ;
37
44
38
45
const BaseWithPlugins = class extends this {
39
- static plugins = currentPlugins . concat ( plugin ) ;
46
+ static plugins = currentPlugins . concat (
47
+ newPlugins . filter ( ( plugin ) => ! currentPlugins . includes ( plugin ) )
48
+ ) ;
40
49
} ;
41
50
42
- type Extension = ReturnTypeOf < T > ;
43
- return BaseWithPlugins as typeof BaseWithPlugins & Constructor < Extension > ;
51
+ return BaseWithPlugins as typeof BaseWithPlugins &
52
+ Constructor < UnionToIntersection < ReturnTypeOf < T1 > & ReturnTypeOf < T2 > > > ;
44
53
}
45
54
46
55
static defaults < S extends Constructor < any > > ( this : S , defaults : Options ) {
@@ -59,7 +68,7 @@ export class Base {
59
68
// apply plugins
60
69
// https://stackoverflow.com/a/16345172
61
70
const classConstructor = this . constructor as typeof Base ;
62
- classConstructor . plugins . forEach ( plugin => {
71
+ classConstructor . plugins . forEach ( ( plugin ) => {
63
72
Object . assign ( this , plugin ( this , options ) ) ;
64
73
} ) ;
65
74
}
0 commit comments