|
|
1 | NO CONTENT: new file 100644 |
| @@ -49,6 +49,8 typescript { | |||
|
|
49 | 49 | compilerOptions { |
|
|
50 | 50 | types = [] |
|
|
51 | 51 | declaration = true |
|
|
52 | experimentalDecorators = true | |
|
|
53 | //strict = true | |
|
|
52 | 54 | |
|
|
53 | 55 | if(symbols != 'none') { |
|
|
54 | 56 | sourceMap = true |
| @@ -10,28 +10,41 type Injector<T> = { | |||
|
|
10 | 10 | [k in keyof T]: Setter; |
|
|
11 | 11 | }; |
|
|
12 | 12 | |
|
|
13 | type Compatible<T1, T2> = T1 extends T2 ? any : never; | |
|
|
14 | ||
|
|
15 | type SetterType<T> = T extends (v: infer V) => void ? V : never; | |
|
|
16 | ||
|
|
17 | type Tuple<T = any> = Parameters<(...args: T[]) => void>; | |
|
|
18 | ||
|
|
19 | interface Newable<A extends Tuple, T> { | |
|
|
20 | new (...params: A): T; | |
|
|
21 | prototype: T; | |
|
|
22 | } | |
|
|
23 | ||
|
|
24 | type MapTuple<T, A extends (keyof T)[]> = { [K in keyof A] : K extends number ? T[ A[K] ] : A[K] }; | |
|
|
25 | ||
|
|
13 | 26 | export class Builder<T, S> { |
|
|
14 |
provides( |
|
|
|
27 | provides() { | |
|
|
15 | 28 | return <C extends Constructor<T>>(constructor: C) => { |
|
|
16 | 29 | return constructor; |
|
|
17 | 30 | }; |
|
|
18 | 31 | } |
|
|
19 | 32 | |
|
|
20 | 33 | inject<K extends keyof S>(dependency: K) { |
|
|
21 | return <M extends keyof T>(target: any, memberName: M, descriptor: TypedPropertyDescriptor<Setter<S[K]>> ) => { | |
|
|
34 | // K = "bar" | |
|
|
35 | // M = "setValue" | |
|
|
36 | // S[K] = Bar | |
|
|
37 | // T[M] = (value: string) => void | |
|
|
38 | // P[m] = (value: V) => void | |
|
|
39 | return <P, M extends keyof (T | P)>(target: P, memberName: M, descriptor: TypedPropertyDescriptor<Compatible<T[M], Setter<S[K]>>>) => { | |
|
|
22 | 40 | |
|
|
23 | 41 | }; |
|
|
24 | 42 | } |
|
|
25 | 43 | |
|
|
26 |
|
|
|
|
27 | return <M extends keyof T>(target: any, memberName: M, descriptor: TypedPropertyDescriptor<S[K]> ) => { | |
|
|
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 | } | |
|
|
28 | 49 | |
|
|
29 | }; | |
|
|
30 | } | |
|
|
31 | 50 | } |
|
|
32 | ||
|
|
33 | export function inject<I extends Injector<I> >(dependency: string) { | |
|
|
34 | return <M extends keyof I>(target: any, memberName: M, descriptor: TypedPropertyDescriptor<I[M]> ) => { | |
|
|
35 | ||
|
|
36 | }; | |
|
|
37 | } | |
| @@ -3,10 +3,16 import { Foo } from "./Foo"; | |||
|
|
3 | 3 | export class Bar { |
|
|
4 | 4 | name = "bar"; |
|
|
5 | 5 | |
|
|
6 | foo: Foo; | |
|
|
6 | foo: Foo | undefined; | |
|
|
7 | 7 | |
|
|
8 | constructor(_opts) { | |
|
|
8 | constructor(_opts?: { foo?: Foo; }) { | |
|
|
9 | 9 | if (_opts && _opts.foo) |
|
|
10 | 10 | this.foo = _opts.foo; |
|
|
11 | 11 | } |
|
|
12 | ||
|
|
13 | getFoo() { | |
|
|
14 | if (this.foo === undefined) | |
|
|
15 | throw new Error("The foo isn't set"); | |
|
|
16 | return this.foo; | |
|
|
17 | } | |
|
|
12 | 18 | } |
| @@ -2,22 +2,32 import { Builder } from "../di/Annotatio | |||
|
|
2 | 2 | import { Bar } from "./Bar"; |
|
|
3 | 3 | import { Foo } from "./Foo"; |
|
|
4 | 4 | |
|
|
5 | export interface Injector<T> { | |
|
|
6 | setValue(value: T); | |
|
|
7 | } | |
|
|
5 | const builder = new Builder<Box<Bar>, { bar: Bar; foo: Foo; obj: object }>(); | |
|
|
8 | 6 | |
|
|
9 | const builder = new Builder<Box<any>, { bar: Bar; foo: Foo}>(); | |
|
|
7 | @builder.provides() | |
|
|
8 | @builder.dependencies("bar") | |
|
|
9 | export class Box<T> { | |
|
|
10 | private _value: T | undefined; | |
|
|
10 | 11 | |
|
|
11 | @builder.provides("barBox") | |
|
|
12 | export class Box<T> implements Injector<T> { | |
|
|
13 | private _value: T; | |
|
|
12 | constructor(value: T) { | |
|
|
13 | this._value = value; | |
|
|
14 | } | |
|
|
14 | 15 | |
|
|
15 | 16 | @builder.inject("bar") |
|
|
16 | 17 | setValue(value: T) { |
|
|
17 | 18 | this._value = value; |
|
|
18 | 19 | } |
|
|
19 | 20 | |
|
|
21 | ||
|
|
22 | @builder.inject("foo") | |
|
|
23 | setObj(value: object) { | |
|
|
24 | ||
|
|
25 | } | |
|
|
26 | ||
|
|
20 | 27 | getValue() { |
|
|
28 | if (this._value === undefined) | |
|
|
29 | throw new Error("Trying to get a value from the empty box"); | |
|
|
30 | ||
|
|
21 | 31 | return this._value; |
|
|
22 | 32 | } |
|
|
23 |
} |
|
|
|
33 | } No newline at end of file | |
General Comments 0
You need to be logged in to leave comments.
Login now
