diff --git a/build.gradle b/build.gradle --- a/build.gradle +++ b/build.gradle @@ -49,6 +49,8 @@ typescript { compilerOptions { types = [] declaration = true + experimentalDecorators = true + //strict = true if(symbols != 'none') { sourceMap = true diff --git a/src/main/ts/di/Annotations.ts b/src/main/ts/di/Annotations.ts --- a/src/main/ts/di/Annotations.ts +++ b/src/main/ts/di/Annotations.ts @@ -10,28 +10,41 @@ type Injector = { [k in keyof T]: Setter; }; +type Compatible = T1 extends T2 ? any : never; + +type SetterType = T extends (v: infer V) => void ? V : never; + +type Tuple = Parameters<(...args: T[]) => void>; + +interface Newable { + new (...params: A): T; + prototype: T; +} + +type MapTuple = { [K in keyof A] : K extends number ? T[ A[K] ] : A[K] }; + export class Builder { - provides(name: string) { + provides() { return >(constructor: C) => { return constructor; }; } inject(dependency: K) { - return (target: any, memberName: M, descriptor: TypedPropertyDescriptor> ) => { + // K = "bar" + // M = "setValue" + // S[K] = Bar + // T[M] = (value: string) => void + // P[m] = (value: V) => void + return (target: P, memberName: M, descriptor: TypedPropertyDescriptor>>) => { }; } - prop(dependency: K) { - return (target: any, memberName: M, descriptor: TypedPropertyDescriptor ) => { + dependencies(...deps: D) { + return >(constructor: MapTuple extends ConstructorParameters ? C : never) => { + return constructor; + } ; + } - }; - } } - -export function inject >(dependency: string) { - return (target: any, memberName: M, descriptor: TypedPropertyDescriptor ) => { - - }; -} diff --git a/src/test/ts/mock/Bar.ts b/src/test/ts/mock/Bar.ts --- a/src/test/ts/mock/Bar.ts +++ b/src/test/ts/mock/Bar.ts @@ -3,10 +3,16 @@ import { Foo } from "./Foo"; export class Bar { name = "bar"; - foo: Foo; + foo: Foo | undefined; - constructor(_opts) { + constructor(_opts?: { foo?: Foo; }) { if (_opts && _opts.foo) this.foo = _opts.foo; } + + getFoo() { + if (this.foo === undefined) + throw new Error("The foo isn't set"); + return this.foo; + } } diff --git a/src/test/ts/mock/Box.ts b/src/test/ts/mock/Box.ts --- a/src/test/ts/mock/Box.ts +++ b/src/test/ts/mock/Box.ts @@ -2,22 +2,32 @@ import { Builder } from "../di/Annotatio import { Bar } from "./Bar"; import { Foo } from "./Foo"; -export interface Injector { - setValue(value: T); -} +const builder = new Builder, { bar: Bar; foo: Foo; obj: object }>(); -const builder = new Builder, { bar: Bar; foo: Foo}>(); +@builder.provides() +@builder.dependencies("bar") +export class Box { + private _value: T | undefined; -@builder.provides("barBox") -export class Box implements Injector { - private _value: T; + constructor(value: T) { + this._value = value; + } @builder.inject("bar") setValue(value: T) { this._value = value; } + + @builder.inject("foo") + setObj(value: object) { + + } + getValue() { + if (this._value === undefined) + throw new Error("Trying to get a value from the empty box"); + return this._value; } -} +} \ No newline at end of file diff --git a/src/test/ts/mock/config.ts b/src/test/ts/mock/config.ts new file mode 100644 diff --git a/src/test/tsconfig.json b/src/test/tsconfig.json --- a/src/test/tsconfig.json +++ b/src/test/tsconfig.json @@ -1,7 +1,7 @@ { "extends": "../tsconfig", "compilerOptions": { - "rootDir": "ts", + //"rootDir": "ts", "baseUrl": ".", "rootDirs": [ "ts", diff --git a/src/tsconfig.json b/src/tsconfig.json --- a/src/tsconfig.json +++ b/src/tsconfig.json @@ -4,6 +4,7 @@ "experimentalDecorators": true, "noEmitOnError": true, "listFiles": true, + "strict": true, "types": [], "target": "ES5", "lib": ["es5", "es2015.promise", "es2015.symbol", "es2015.iterable", "dom", "scripthost"]