##// END OF EJS Templates
working on di decorators
cin -
r109:f71c50acc9f9 ioc ts support
parent child
Show More
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(name: string) {
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 prop<K extends keyof S>(dependency: K) {
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
@@ -1,7 +1,7
1 1 {
2 2 "extends": "../tsconfig",
3 3 "compilerOptions": {
4 "rootDir": "ts",
4 //"rootDir": "ts",
5 5 "baseUrl": ".",
6 6 "rootDirs": [
7 7 "ts",
@@ -4,6 +4,7
4 4 "experimentalDecorators": true,
5 5 "noEmitOnError": true,
6 6 "listFiles": true,
7 "strict": true,
7 8 "types": [],
8 9 "target": "ES5",
9 10 "lib": ["es5", "es2015.promise", "es2015.symbol", "es2015.iterable", "dom", "scripthost"]
General Comments 0
You need to be logged in to leave comments. Login now