| @@ -6,27 +6,20 export interface InjectOptions { | |||
|
|
6 | 6 | |
|
|
7 | 7 | type Setter<T = any> = (v: T) => void; |
|
|
8 | 8 | |
|
|
9 | type Injector<T> = { | |
|
|
10 | [k in keyof T]: Setter; | |
|
|
11 | }; | |
|
|
12 | ||
|
|
13 | 9 | type Compatible<T1, T2> = T1 extends T2 ? any : never; |
|
|
14 | 10 | |
|
|
15 | 11 | type SetterType<T> = T extends (v: infer V) => void ? V : never; |
|
|
16 | 12 | |
|
|
17 | type Tuple<T = any> = Parameters<(...args: T[]) => void>; | |
|
|
13 | type ExtractService<K, S> = K extends keyof S ? S[K] : K; | |
|
|
18 | 14 | |
|
|
19 | interface Newable<A extends Tuple, T> { | |
|
|
20 | new (...params: A): T; | |
|
|
21 | prototype: T; | |
|
|
22 | } | |
|
|
15 | type ExtractDependency<D, S> = D extends { $dependency: infer K } ? D extends { lazy: true } ? () => ExtractService<K, S> : ExtractService<K, S> : VisitDependency<D, S>; | |
|
|
23 | 16 | |
|
|
24 | type MapTuple<T, A extends (keyof T)[]> = { [K in keyof A] : K extends number ? T[ A[K] ] : A[K] }; | |
|
|
17 | type VisitDependency<D, S> = D extends {} ? { [K in keyof D]: ExtractDependency<D[K], S> } : D; | |
|
|
25 | 18 | |
|
|
26 | 19 | export class Builder<T, S> { |
|
|
27 | provides() { | |
|
|
28 |
return <C extends |
|
|
|
29 | return constructor; | |
|
|
20 | consume<P extends any[]>(...args: P) { | |
|
|
21 | return <C extends new (...args: ExtractDependency<P, S>) => T>(constructor: C) => { | |
|
|
22 | // return constructor; | |
|
|
30 | 23 | }; |
|
|
31 | 24 | } |
|
|
32 | 25 | |
| @@ -41,10 +34,4 export class Builder<T, S> { | |||
|
|
41 | 34 | }; |
|
|
42 | 35 | } |
|
|
43 | 36 | |
|
|
44 | dependencies<D extends (keyof S)[]>(...deps: D) { | |
|
|
45 | return <C extends Constructor<T>>(constructor: MapTuple<S, D> extends ConstructorParameters<C> ? C : never) => { | |
|
|
46 | return constructor; | |
|
|
47 | } ; | |
|
|
48 | 37 | } |
|
|
49 | ||
|
|
50 | } | |
| @@ -55,7 +55,7 export interface IActivatable { | |||
|
|
55 | 55 | * can be activated and manages the active state of the |
|
|
56 | 56 | * component |
|
|
57 | 57 | */ |
|
|
58 | setActivationController(controller: IActivationController); | |
|
|
58 | setActivationController(controller: IActivationController): void; | |
|
|
59 | 59 | |
|
|
60 | 60 | /** |
|
|
61 | 61 | * Gets the current activation controller for this component |
| @@ -1,18 +1,33 | |||
|
|
1 | 1 | import { Foo } from "./Foo"; |
|
|
2 | import { config } from "./config"; | |
|
|
2 | 3 | |
|
|
3 | export class Bar { | |
|
|
4 | name = "bar"; | |
|
|
4 | const service = config.build("bar"); | |
|
|
5 | 5 | |
|
|
6 | foo: Foo | undefined; | |
|
|
6 | @service.consume({ | |
|
|
7 | f: config.dependency("foo"), | |
|
|
8 | nested: { | |
|
|
9 | lazy: config.lazy("foo") | |
|
|
10 | } | |
|
|
11 | }) | |
|
|
12 | export class Bar { | |
|
|
13 | barName = "bar"; | |
|
|
7 | 14 | |
|
|
8 | constructor(_opts?: { foo?: Foo; }) { | |
|
|
9 | if (_opts && _opts.foo) | |
|
|
10 | this.foo = _opts.foo; | |
|
|
15 | _v: Foo | undefined; | |
|
|
16 | ||
|
|
17 | constructor(_opts: { | |
|
|
18 | f: Foo; | |
|
|
19 | nested: { | |
|
|
20 | lazy: () => Foo | |
|
|
21 | } | |
|
|
22 | }) { | |
|
|
23 | ||
|
|
24 | if (_opts && _opts.f) | |
|
|
25 | this._v = _opts.f; | |
|
|
11 | 26 | } |
|
|
12 | 27 | |
|
|
13 | 28 | getFoo() { |
|
|
14 |
if (this. |
|
|
|
29 | if (this._v === undefined) | |
|
|
15 | 30 | throw new Error("The foo isn't set"); |
|
|
16 |
return this. |
|
|
|
31 | return this._v; | |
|
|
17 | 32 | } |
|
|
18 | 33 | } |
| @@ -1,8 +1,8 | |||
|
|
1 | 1 | import { config } from "./config"; |
|
|
2 | 2 | |
|
|
3 |
const service = config. |
|
|
|
3 | const service = config.build("barBox"); | |
|
|
4 | 4 | |
|
|
5 | @service.provides() | |
|
|
5 | @service.consume(config.dependency("bar")) | |
|
|
6 | 6 | export class Box<T> { |
|
|
7 | 7 | private _value: T | undefined; |
|
|
8 | 8 | |
| @@ -15,7 +15,6 export class Box<T> { | |||
|
|
15 | 15 | this._value = value; |
|
|
16 | 16 | } |
|
|
17 | 17 | |
|
|
18 | @service.inject("foo") | |
|
|
19 | 18 | setObj(value: object) { |
|
|
20 | 19 | |
|
|
21 | 20 | } |
| @@ -26,4 +25,4 export class Box<T> { | |||
|
|
26 | 25 | |
|
|
27 | 26 | return this._value; |
|
|
28 | 27 | } |
|
|
29 | } No newline at end of file | |
|
|
28 | } | |
| @@ -8,8 +8,27 interface RegistrationOptions { | |||
|
|
8 | 8 | activation?: ActivationType; |
|
|
9 | 9 | } |
|
|
10 | 10 | |
|
|
11 | interface Dependency<K extends keyof any> { | |
|
|
12 | $dependency: K; | |
|
|
13 | ||
|
|
14 | lazy?: boolean; | |
|
|
15 | } | |
|
|
16 | ||
|
|
17 | interface Lazy<K extends keyof any> extends Dependency<K> { | |
|
|
18 | lazy: true; | |
|
|
19 | } | |
|
|
20 | ||
|
|
21 | type PromiseOrValue<T> = T | PromiseLike<T>; | |
|
|
22 | ||
|
|
11 | 23 | interface ConfigBuilder<S> { |
|
|
12 |
|
|
|
|
24 | build<K extends keyof S, T = S[K]>(name: K): Builder<T, S>; | |
|
|
25 | ||
|
|
26 | dependency<K extends keyof S>(name: K): Dependency<K>; | |
|
|
27 | ||
|
|
28 | lazy<K extends keyof S>(name: K): Lazy<K>; | |
|
|
29 | ||
|
|
30 | mapTo<K extends keyof S>(name: K, ctor: () => PromiseOrValue<new (...args: any[]) => S[K]>): ConfigBuilder<S>; | |
|
|
31 | ||
|
|
13 | 32 | } |
|
|
14 | 33 | |
|
|
15 | 34 | interface ContainerServices { |
| @@ -26,4 +45,23 interface ContainerServices { | |||
|
|
26 | 45 | timeout: number; |
|
|
27 | 46 | } |
|
|
28 | 47 | |
|
|
48 | declare function load<M, C extends keyof M>(m: PromiseLike<M>, name: C): () => PromiseLike<M[C]>; | |
|
|
49 | ||
|
|
50 | const t = { | |
|
|
51 | barBox: load(import("./Box"), "Box"), | |
|
|
52 | ||
|
|
53 | foo: async () => (await import("./Bar")).Bar, | |
|
|
54 | ||
|
|
55 | bar: Bar, | |
|
|
56 | ||
|
|
57 | password: String, | |
|
|
58 | ||
|
|
59 | user: String, | |
|
|
60 | ||
|
|
61 | timeout: Number | |
|
|
62 | }; | |
|
|
63 | ||
|
|
29 | 64 | export declare const config: ConfigBuilder<ContainerServices>; |
|
|
65 | config | |
|
|
66 | .mapTo("bar", ) | |
|
|
67 | .mapTo("barBox", ; | |
General Comments 0
You need to be logged in to leave comments.
Login now
