-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbase-class-system.d.ts
91 lines (81 loc) · 2.57 KB
/
base-class-system.d.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
// Type definitions for the Base.js class system from 2006
// Largely inspired by UCCTD's definitions for the Impact Class System, which
// is based on John Resig's "Simple JavaScript Inheritance" system from 2008.
// Thanks to Nax for helping with Base.js' extra `_static` argument support for
// `extend` calls
export {};
declare global {
type ReplaceThisParameter<T, This2> = T extends (
this: infer This,
...args: infer Args
) => infer Return
? unknown extends This
? T
: (this: This2, ...args: Args) => Return
: T;
type ClassMethodThis<
K extends keyof Prototype,
Constructor,
Prototype,
ParentPrototype,
> = K extends keyof ParentPrototype
? Prototype & { constructor: Constructor; parent: ParentPrototype }
: Prototype & { constructor: Constructor };
type ClassMember<
Key extends keyof Prototype,
Constructor,
Prototype,
ParentPrototype,
> = ReplaceThisParameter<
Prototype[Key],
ClassMethodThis<Key, Constructor, Prototype, ParentPrototype>
>;
type ClassDefinition<Constructor, Prototype, ParentPrototype> = {
[K in keyof Prototype]?: ClassMember<
K,
Constructor,
Prototype,
ParentPrototype
> | null;
};
type ClassStaticMember<
Key extends keyof Prototype,
Prototype,
> = Prototype[Key] extends (
this: infer This,
...args: infer Args
) => infer Return
? unknown extends This
? Prototype[Key]
: (this: This, ...args: Args) => Return
: Prototype[Key];
type ClassStaticDefinition<Prototype> = {
[K in keyof Prototype]?: ClassStaticMember<K, Prototype> | null;
};
type ClassPrototype<Constructor, Instance, Static> = Constructor extends new (
...args: infer Args
) => Instance
? { [K in keyof Instance]: Instance[K] } & {
[K in keyof Static]: Static[K];
} & {
init: (this: Instance & Static, ...args: Args) => void;
staticInstantiate: (
this: Instance & Static,
...args: Args
) => (Instance & Static) | null | undefined;
}
: Instance;
interface InstanceClass<Instance, Static> {
extend<ChildConstructor extends { prototype: unknown }>(
this: this,
instanceDefinition: ClassDefinition<
ChildConstructor,
ChildConstructor['prototype'],
this['prototype']
>,
staticDefinition?: ClassStaticDefinition<ChildConstructor['prototype']>,
): ChildConstructor;
readonly prototype: ClassPrototype<this, Instance, Static>;
}
type BaseClass<Instance, Static> = InstanceClass<Instance, Static> & Static;
}