| @@ -1,37 +1,41 | |||||
| 1 | import { Constructor } from "../interfaces"; |
|
1 | import { Constructor } from "../interfaces"; | |
| 2 |
|
2 | |||
| 3 | export interface InjectOptions { |
|
3 | export interface InjectOptions { | |
| 4 | lazy?: boolean; |
|
4 | lazy?: boolean; | |
| 5 | } |
|
5 | } | |
| 6 |
|
6 | |||
| 7 | type Setter<T = any> = (v: T) => void; |
|
7 | type Setter<T = any> = (v: T) => void; | |
| 8 |
|
8 | |||
| 9 | type Compatible<T1, T2> = T1 extends T2 ? any : never; |
|
9 | type Compatible<T1, T2> = T1 extends T2 ? any : never; | |
| 10 |
|
10 | |||
| 11 | type SetterType<T> = T extends (v: infer V) => void ? V : never; |
|
11 | type SetterType<T> = T extends (v: infer V) => void ? V : never; | |
| 12 |
|
12 | |||
| 13 | type ExtractService<K, S> = K extends keyof S ? S[K] : K; |
|
13 | type ExtractService<K, S> = K extends keyof S ? S[K] : K; | |
| 14 |
|
14 | |||
| 15 | type ExtractDependency<D, S> = D extends { $dependency: infer K } ? D extends { lazy: true } ? () => ExtractService<K, S> : ExtractService<K, S> : VisitDependency<D, S>; |
|
15 | type ExtractDependency<D, S> = D extends { $dependency: infer K } ? D extends { lazy: true } ? () => ExtractService<K, S> : ExtractService<K, S> : VisitDependency<D, S>; | |
| 16 |
|
16 | |||
| 17 | type VisitDependency<D, S> = D extends {} ? { [K in keyof D]: ExtractDependency<D[K], S> } : D; |
|
17 | type VisitDependency<D, S> = D extends {} ? { [K in keyof D]: ExtractDependency<D[K], S> } : D; | |
| 18 |
|
18 | |||
| 19 | export class Builder<T, S> { |
|
19 | export class Builder<T, S> { | |
| 20 | consume<P extends any[]>(...args: P) { |
|
20 | consume<P extends any[]>(...args: P) { | |
| 21 | return <C extends new (...args: ExtractDependency<P, S>) => T>(constructor: C) => { |
|
21 | return <C extends new (...args: ExtractDependency<P, S>) => T>(constructor: C) => { | |
| 22 | // return constructor; |
|
22 | return constructor as typeof constructor & { service: () => T }; | |
| 23 |
|
|
23 | }; | |
| 24 | } |
|
24 | } | |
| 25 |
|
25 | |||
| 26 | inject<K extends keyof S>(dependency: K) { |
|
26 | inject<K extends keyof S>(dependency: K) { | |
| 27 | // K = "bar" |
|
27 | // K = "bar" | |
| 28 | // M = "setValue" |
|
28 | // M = "setValue" | |
| 29 | // S[K] = Bar |
|
29 | // S[K] = Bar | |
| 30 | // T[M] = (value: string) => void |
|
30 | // T[M] = (value: string) => void | |
| 31 | // P[m] = (value: V) => void |
|
31 | // P[m] = (value: V) => void | |
| 32 | return <P, M extends keyof (T | P)>(target: P, memberName: M, descriptor: TypedPropertyDescriptor<Compatible<T[M], Setter<S[K]>>>) => { |
|
32 | return <P, M extends keyof (T | P)>(target: P, memberName: M, descriptor: TypedPropertyDescriptor<Compatible<T[M], Setter<S[K]>>>) => { | |
| 33 |
|
33 | |||
| 34 | }; |
|
34 | }; | |
| 35 | } |
|
35 | } | |
| 36 |
|
36 | |||
|
|
37 | cast<T2 extends T>(): Builder<T2, S> { | |||
|
|
38 | return this as Builder<T2, S>; | |||
| 37 | } |
|
39 | } | |
|
|
40 | ||||
|
|
41 | } | |||
| @@ -1,28 +1,28 | |||||
| 1 | import { config } from "./config"; |
|
1 | import { config } from "./config"; | |
| 2 |
|
2 | |||
| 3 | const service = config.build("barBox"); |
|
3 | const service = config.build("barBox"); | |
| 4 |
|
4 | |||
| 5 | @service.consume(config.dependency("bar")) |
|
5 | @service.consume(config.dependency("bar")) | |
| 6 | export class Box<T> { |
|
6 | export class Box<T> { | |
| 7 | private _value: T | undefined; |
|
7 | private _value: T | undefined; | |
| 8 |
|
8 | |||
| 9 | constructor(value: T) { |
|
9 | constructor(value: T) { | |
| 10 | this._value = value; |
|
10 | this._value = value; | |
| 11 | } |
|
11 | } | |
| 12 |
|
12 | |||
| 13 | @service.inject("bar") |
|
13 | @service.inject("bar") | |
| 14 | setValue(value: T) { |
|
14 | setValue(value: T) { | |
| 15 | this._value = value; |
|
15 | this._value = value; | |
| 16 | } |
|
16 | } | |
| 17 |
|
17 | |||
| 18 | setObj(value: object) { |
|
18 | setObj(value: object) { | |
| 19 |
|
19 | |||
| 20 | } |
|
20 | } | |
| 21 |
|
21 | |||
| 22 | getValue() { |
|
22 | getValue() { | |
| 23 | if (this._value === undefined) |
|
23 | if (this._value === undefined) | |
| 24 | throw new Error("Trying to get a value from the empty box"); |
|
24 | throw new Error("Trying to get a value from the empty box"); | |
| 25 |
|
25 | |||
| 26 | return this._value; |
|
26 | return this._value; | |
| 27 | } |
|
27 | } | |
| 28 |
} |
|
28 | } No newline at end of file | |
| @@ -1,67 +1,68 | |||||
| 1 | import { Foo } from "./Foo"; |
|
1 | import { Foo } from "./Foo"; | |
| 2 | import { Bar } from "./Bar"; |
|
2 | import { Bar } from "./Bar"; | |
| 3 | import { ActivationType } from "../di/interfaces"; |
|
3 | import { ActivationType } from "../di/interfaces"; | |
| 4 | import { Builder } from "../di/Annotations"; |
|
4 | import { Builder } from "../di/Annotations"; | |
| 5 | import { Box } from "./Box"; |
|
5 | import { Box } from "./Box"; | |
| 6 |
|
6 | |||
| 7 | interface RegistrationOptions { |
|
7 | interface RegistrationOptions { | |
| 8 | activation?: ActivationType; |
|
8 | activation?: ActivationType; | |
| 9 | } |
|
9 | } | |
| 10 |
|
10 | |||
| 11 | interface Dependency<K extends keyof any> { |
|
11 | interface Dependency<K extends keyof any> { | |
| 12 | $dependency: K; |
|
12 | $dependency: K; | |
| 13 |
|
13 | |||
| 14 | lazy?: boolean; |
|
14 | lazy?: boolean; | |
| 15 | } |
|
15 | } | |
| 16 |
|
16 | |||
| 17 | interface Lazy<K extends keyof any> extends Dependency<K> { |
|
17 | interface Lazy<K extends keyof any> extends Dependency<K> { | |
| 18 | lazy: true; |
|
18 | lazy: true; | |
| 19 | } |
|
19 | } | |
| 20 |
|
20 | |||
| 21 | type PromiseOrValue<T> = T | PromiseLike<T>; |
|
21 | type PromiseOrValue<T> = T | PromiseLike<T>; | |
| 22 |
|
22 | |||
| 23 | interface ConfigBuilder<S> { |
|
23 | interface ConfigBuilder<S> { | |
| 24 | build<K extends keyof S, T = S[K]>(name: K): Builder<T, S>; |
|
24 | build<K extends keyof S, T = S[K]>(name: K): Builder<T, S>; | |
| 25 |
|
25 | |||
| 26 | dependency<K extends keyof S>(name: K): Dependency<K>; |
|
26 | dependency<K extends keyof S>(name: K): Dependency<K>; | |
| 27 |
|
27 | |||
| 28 | lazy<K extends keyof S>(name: K): Lazy<K>; |
|
28 | lazy<K extends keyof S>(name: K): Lazy<K>; | |
| 29 |
|
29 | |||
| 30 | mapTo<K extends keyof S>(name: K, ctor: () => PromiseOrValue<new (...args: any[]) => S[K]>): ConfigBuilder<S>; |
|
30 | mapTo<K extends keyof S>(name: K, ctor: () => PromiseOrValue<new (...args: any[]) => S[K]>): ConfigBuilder<S>; | |
| 31 |
|
31 | |||
| 32 | } |
|
32 | } | |
| 33 |
|
33 | |||
| 34 | interface ContainerServices { |
|
34 | interface ContainerServices { | |
| 35 | barBox: Box<Bar>; |
|
35 | barBox: Box<Bar>; | |
| 36 |
|
36 | |||
| 37 | foo: Foo; |
|
37 | foo: Foo; | |
| 38 |
|
38 | |||
| 39 | bar: Bar; |
|
39 | bar: Bar; | |
| 40 |
|
40 | |||
| 41 | password: string; |
|
41 | password: string; | |
| 42 |
|
42 | |||
| 43 | user: string; |
|
43 | user: string; | |
| 44 |
|
44 | |||
| 45 | timeout: number; |
|
45 | timeout: number; | |
| 46 | } |
|
46 | } | |
| 47 |
|
47 | |||
| 48 | declare function load<M, C extends keyof M>(m: PromiseLike<M>, name: C): () => PromiseLike<M[C]>; |
|
48 | declare function load<M, C extends keyof M>(m: PromiseLike<M>, name: C): () => PromiseLike<M[C]>; | |
| 49 |
|
49 | |||
| 50 | const t = { |
|
50 | const t = { | |
| 51 | barBox: load(import("./Box"), "Box"), |
|
51 | barBox: load(import("./Box"), "Box"), | |
| 52 |
|
52 | |||
| 53 | foo: async () => (await import("./Bar")).Bar, |
|
53 | foo: async () => (await import("./Bar")).Bar, | |
| 54 |
|
54 | |||
| 55 | bar: Bar, |
|
55 | bar: Bar, | |
| 56 |
|
56 | |||
| 57 | password: String, |
|
57 | password: String, | |
| 58 |
|
58 | |||
| 59 | user: String, |
|
59 | user: String, | |
| 60 |
|
60 | |||
| 61 | timeout: Number |
|
61 | timeout: Number | |
| 62 | }; |
|
62 | }; | |
| 63 |
|
63 | |||
|
|
64 | declare const bc: typeof Box; | |||
|
|
65 | ||||
|
|
66 | const x = new bc(); | |||
|
|
67 | ||||
| 64 | export declare const config: ConfigBuilder<ContainerServices>; |
|
68 | 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
