|
3 | 3 | export type ModuleKey = symbol | string; |
4 | 4 |
|
5 | 5 | export interface DependencyObject { |
6 | | - [key: string]: DependencyKey; |
| 6 | + [key: string]: DependencyKey; |
7 | 7 | } |
8 | 8 |
|
9 | 9 | export type DependencyArray = DependencyKey[]; |
10 | 10 |
|
11 | 11 | export type Scope = 'singleton' | 'transient' | 'scoped'; |
12 | 12 |
|
13 | 13 | export interface DefaultRegistry { |
14 | | - [key: string]: unknown; |
| 14 | + [key: string]: unknown; |
15 | 15 | } |
16 | 16 |
|
17 | 17 | type RegistryKey<TRegistry> = Extract<keyof TRegistry, DependencyKey>; |
18 | 18 |
|
| 19 | +type RegistryDependencyArray<TRegistry> = readonly RegistryKey<TRegistry>[]; |
| 20 | + |
| 21 | +type RegistryDependencyObject<TRegistry> = { |
| 22 | + [key: string]: RegistryKey<TRegistry>; |
| 23 | +}; |
| 24 | + |
| 25 | +type RegistryDependencies<TRegistry> = RegistryDependencyArray<TRegistry> | RegistryDependencyObject<TRegistry>; |
| 26 | + |
19 | 27 | type IncompatibleOverride<K extends PropertyKey, Expected, Provided> = { |
20 | | - __error: 'Incompatible override type for registry key'; |
21 | | - key: K; |
22 | | - expected: Expected; |
23 | | - provided: Provided; |
| 28 | + __error: 'Incompatible override type for registry key'; |
| 29 | + key: K; |
| 30 | + expected: Expected; |
| 31 | + provided: Provided; |
24 | 32 | }; |
25 | 33 |
|
26 | 34 | type CompatibleKey<TRegistry, TOverride> = [TOverride] extends [never] |
27 | | - ? RegistryKey<TRegistry> |
28 | | - : { |
29 | | - [K in RegistryKey<TRegistry>]: TOverride extends TRegistry[K] |
30 | | - ? K |
31 | | - : IncompatibleOverride<K, TRegistry[K], TOverride> |
32 | | - }[RegistryKey<TRegistry>]; |
| 35 | + ? RegistryKey<TRegistry> |
| 36 | + : { |
| 37 | + [K in RegistryKey<TRegistry>]: TOverride extends TRegistry[K] |
| 38 | + ? K |
| 39 | + : IncompatibleOverride<K, TRegistry[K], TOverride> |
| 40 | + }[RegistryKey<TRegistry>]; |
33 | 41 |
|
34 | 42 |
|
35 | 43 | interface Bindable { |
36 | | - bind(key: DependencyKey): { |
37 | | - toValue: (value: unknown) => void; |
38 | | - toFunction: (fn: CallableFunction) => void; |
39 | | - toHigherOrderFunction: ( |
40 | | - fn: CallableFunction, |
41 | | - dependencies?: DependencyArray | DependencyObject, |
42 | | - scope?: Scope |
43 | | - ) => void; |
44 | | - toCurry: ( |
45 | | - fn: CallableFunction, |
46 | | - dependencies?: DependencyArray | DependencyObject, |
47 | | - scope?: Scope |
48 | | - ) => void; |
49 | | - toFactory: (factory: CallableFunction, scope?: Scope) => void; |
50 | | - toClass: <C>( |
51 | | - constructor: new (...args: any[]) => C, |
52 | | - dependencies?: DependencyArray | DependencyObject, |
53 | | - scope?: Scope |
54 | | - ) => void; |
55 | | - }; |
| 44 | + bind(key: DependencyKey): { |
| 45 | + toValue: (value: unknown) => void; |
| 46 | + toFunction: (fn: CallableFunction) => void; |
| 47 | + toHigherOrderFunction: ( |
| 48 | + fn: CallableFunction, |
| 49 | + dependencies?: DependencyArray | DependencyObject, |
| 50 | + scope?: Scope |
| 51 | + ) => void; |
| 52 | + toCurry: ( |
| 53 | + fn: CallableFunction, |
| 54 | + dependencies?: DependencyArray | DependencyObject, |
| 55 | + scope?: Scope |
| 56 | + ) => void; |
| 57 | + toFactory: (factory: CallableFunction, scope?: Scope) => void; |
| 58 | + toClass: <C>( |
| 59 | + constructor: new (...args: any[]) => C, |
| 60 | + dependencies?: DependencyArray | DependencyObject, |
| 61 | + scope?: Scope |
| 62 | + ) => void; |
| 63 | + }; |
56 | 64 | } |
57 | 65 |
|
58 | 66 | interface TypedBindable<TRegistry> { |
59 | | - bind<K extends RegistryKey<TRegistry>>(key: K): { |
60 | | - toValue: (value: TRegistry[K]) => void; |
61 | | - toFunction: (fn: CallableFunction) => void; |
62 | | - toHigherOrderFunction: ( |
63 | | - fn: CallableFunction, |
64 | | - dependencies?: DependencyArray | DependencyObject, |
65 | | - scope?: Scope |
66 | | - ) => void; |
67 | | - toCurry: ( |
68 | | - fn: CallableFunction, |
69 | | - dependencies?: DependencyArray | DependencyObject, |
70 | | - scope?: Scope |
71 | | - ) => void; |
72 | | - toFactory: (factory: CallableFunction, scope?: Scope) => void; |
73 | | - toClass: <C>( |
74 | | - constructor: new (...args: any[]) => C, |
75 | | - dependencies?: DependencyArray | DependencyObject, |
76 | | - scope?: Scope |
77 | | - ) => void; |
78 | | - }; |
79 | | - bind(key: DependencyKey): { |
80 | | - toValue: (value: unknown) => void; |
81 | | - toFunction: (fn: CallableFunction) => void; |
82 | | - toHigherOrderFunction: ( |
83 | | - fn: CallableFunction, |
84 | | - dependencies?: DependencyArray | DependencyObject, |
85 | | - scope?: Scope |
86 | | - ) => void; |
87 | | - toCurry: ( |
88 | | - fn: CallableFunction, |
89 | | - dependencies?: DependencyArray | DependencyObject, |
90 | | - scope?: Scope |
91 | | - ) => void; |
92 | | - toFactory: (factory: CallableFunction, scope?: Scope) => void; |
93 | | - toClass: <C>( |
94 | | - constructor: new (...args: any[]) => C, |
95 | | - dependencies?: DependencyArray | DependencyObject, |
96 | | - scope?: Scope |
97 | | - ) => void; |
98 | | - }; |
| 67 | + bind<K extends RegistryKey<TRegistry>>(key: K): { |
| 68 | + toValue: (value: TRegistry[K]) => void; |
| 69 | + toFunction: (fn: CallableFunction) => void; |
| 70 | + toHigherOrderFunction: ( |
| 71 | + fn: CallableFunction, |
| 72 | + dependencies?: RegistryDependencies<TRegistry>, |
| 73 | + scope?: Scope |
| 74 | + ) => void; |
| 75 | + toCurry: ( |
| 76 | + fn: CallableFunction, |
| 77 | + dependencies?: RegistryDependencies<TRegistry>, |
| 78 | + scope?: Scope |
| 79 | + ) => void; |
| 80 | + toFactory: (factory: CallableFunction, scope?: Scope) => void; |
| 81 | + toClass: <C>( |
| 82 | + constructor: new (...args: any[]) => C, |
| 83 | + dependencies?: RegistryDependencies<TRegistry>, |
| 84 | + scope?: Scope |
| 85 | + ) => void; |
| 86 | + }; |
| 87 | + |
| 88 | + bind(key: DependencyKey): { |
| 89 | + toValue: (value: unknown) => void; |
| 90 | + toFunction: (fn: CallableFunction) => void; |
| 91 | + toHigherOrderFunction: ( |
| 92 | + fn: CallableFunction, |
| 93 | + dependencies?: DependencyArray | DependencyObject, |
| 94 | + scope?: Scope |
| 95 | + ) => void; |
| 96 | + toCurry: ( |
| 97 | + fn: CallableFunction, |
| 98 | + dependencies?: DependencyArray | DependencyObject, |
| 99 | + scope?: Scope |
| 100 | + ) => void; |
| 101 | + toFactory: (factory: CallableFunction, scope?: Scope) => void; |
| 102 | + toClass: <C>( |
| 103 | + constructor: new (...args: any[]) => C, |
| 104 | + dependencies?: DependencyArray | DependencyObject, |
| 105 | + scope?: Scope |
| 106 | + ) => void; |
| 107 | + }; |
99 | 108 | } |
100 | 109 |
|
101 | 110 | export interface Container extends Bindable { |
102 | | - load(moduleKey: ModuleKey, module: Module): void; |
| 111 | + load(moduleKey: ModuleKey, module: Module): void; |
103 | 112 |
|
104 | | - get<T>(key: DependencyKey): T; |
| 113 | + get<T>(key: DependencyKey): T; |
105 | 114 |
|
106 | | - unload(key: ModuleKey): void; |
| 115 | + unload(key: ModuleKey): void; |
107 | 116 |
|
108 | | - runInScope<T>(callback: () => T): T; |
| 117 | + runInScope<T>(callback: () => T): T; |
109 | 118 | } |
110 | 119 |
|
111 | 120 | export interface TypedContainer<TRegistry> { |
112 | | - bind<K extends keyof TRegistry & DependencyKey>(key: K): { |
113 | | - toValue: (value: TRegistry[K]) => void; |
114 | | - toFunction: (fn: TRegistry[K] extends CallableFunction ? TRegistry[K] : never) => void; |
115 | | - toHigherOrderFunction: ( |
116 | | - fn: CallableFunction, |
117 | | - dependencies?: DependencyArray | DependencyObject, |
118 | | - scope?: Scope |
119 | | - ) => void; |
120 | | - toCurry: ( |
121 | | - fn: CallableFunction, |
122 | | - dependencies?: DependencyArray | DependencyObject, |
123 | | - scope?: Scope |
124 | | - ) => void; |
125 | | - toFactory: (factory: (resolve: (key: DependencyKey) => unknown) => TRegistry[K], scope?: Scope) => void; |
126 | | - toClass: ( |
127 | | - constructor: new (...args: any[]) => TRegistry[K], |
128 | | - dependencies?: DependencyArray | DependencyObject, |
129 | | - scope?: Scope |
130 | | - ) => void; |
131 | | - }; |
132 | | - |
133 | | - load<TModuleRegistry>(moduleKey: ModuleKey, module: TypedModule<TModuleRegistry>): void; |
134 | | - load(moduleKey: ModuleKey, module: Module): void; |
135 | | - |
136 | | - get< |
137 | | - TOverride = never, |
138 | | - K extends CompatibleKey<TRegistry, TOverride> = CompatibleKey<TRegistry, TOverride> |
139 | | - >(key: K): [TOverride] extends [never] ? TRegistry[K & keyof TRegistry] : TOverride; |
140 | | - |
141 | | - unload(key: ModuleKey): void; |
142 | | - |
143 | | - runInScope<T>(callback: () => T): T; |
| 121 | + bind<K extends RegistryKey<TRegistry>>(key: K): { |
| 122 | + toValue: (value: TRegistry[K]) => void; |
| 123 | + toFunction: (fn: TRegistry[K] extends CallableFunction ? TRegistry[K] : never) => void; |
| 124 | + toHigherOrderFunction: ( |
| 125 | + fn: CallableFunction, |
| 126 | + dependencies?: RegistryDependencies<TRegistry>, |
| 127 | + scope?: Scope |
| 128 | + ) => void; |
| 129 | + toCurry: ( |
| 130 | + fn: CallableFunction, |
| 131 | + dependencies?: RegistryDependencies<TRegistry>, |
| 132 | + scope?: Scope |
| 133 | + ) => void; |
| 134 | + toFactory: (factory: (resolve: (key: DependencyKey) => unknown) => TRegistry[K], scope?: Scope) => void; |
| 135 | + toClass: ( |
| 136 | + constructor: new (...args: any[]) => TRegistry[K], |
| 137 | + dependencies?: RegistryDependencies<TRegistry>, |
| 138 | + scope?: Scope |
| 139 | + ) => void; |
| 140 | + }; |
| 141 | + |
| 142 | + load<TModuleRegistry>(moduleKey: ModuleKey, module: TypedModule<TModuleRegistry>): void; |
| 143 | + |
| 144 | + load(moduleKey: ModuleKey, module: Module): void; |
| 145 | + |
| 146 | + get< |
| 147 | + TOverride = never, |
| 148 | + K extends CompatibleKey<TRegistry, TOverride> = CompatibleKey<TRegistry, TOverride> |
| 149 | + >(key: K): [TOverride] extends [never] ? TRegistry[K & keyof TRegistry] : TOverride; |
| 150 | + |
| 151 | + unload(key: ModuleKey): void; |
| 152 | + |
| 153 | + runInScope<T>(callback: () => T): T; |
144 | 154 | } |
145 | 155 |
|
146 | 156 | export interface Module extends Bindable { |
147 | | - bindings: Map<DependencyKey, Binding>; |
| 157 | + bindings: Map<DependencyKey, Binding>; |
148 | 158 | } |
149 | 159 |
|
150 | 160 | export interface TypedModule<TRegistry> extends TypedBindable<TRegistry> { |
151 | | - bindings: Map<DependencyKey, Binding>; |
| 161 | + bindings: Map<DependencyKey, Binding>; |
152 | 162 | } |
153 | 163 |
|
154 | 164 | export interface InjectionTokens { |
155 | | - [key: string]: DependencyKey; |
| 165 | + [key: string]: DependencyKey; |
156 | 166 | } |
157 | 167 |
|
158 | 168 | export type ResolveFunction = (dep: DependencyKey) => unknown; |
159 | 169 |
|
160 | 170 | export interface Binding { |
161 | | - factory: (resolve: (key: DependencyKey) => unknown) => unknown; |
162 | | - scope: Scope; |
| 171 | + factory: (resolve: (key: DependencyKey) => unknown) => unknown; |
| 172 | + scope: Scope; |
163 | 173 | } |
0 commit comments