diff --git a/.changeset/curly-singers-add.md b/.changeset/curly-singers-add.md new file mode 100644 index 00000000..158eec64 --- /dev/null +++ b/.changeset/curly-singers-add.md @@ -0,0 +1,5 @@ +--- +"@inversifyjs/strongly-typed": minor +--- + +Added `TypedMultiInject` diff --git a/packages/container/libraries/strongly-typed/README.md b/packages/container/libraries/strongly-typed/README.md index 90ffbd9e..2b1c6f4c 100644 --- a/packages/container/libraries/strongly-typed/README.md +++ b/packages/container/libraries/strongly-typed/README.md @@ -67,10 +67,11 @@ The library also exposes a `TypedInject` type that will leverage the `BindingMap You'll need to re-export the `inject` decorator with a type assertion: ```ts -import { inject } from 'inversify'; -import type { TypedInject } from '@inversifyjs/strongly-typed'; +import { inject, multiInject } from 'inversify'; +import type { TypedInject, TypedMultiInject } from '@inversifyjs/strongly-typed'; export const $inject = inject as TypedInject; +export const $multiInject = multiInject as TypedMultiInject; ``` You can now use this to strongly type injected constructor parameters, or **public** properties: diff --git a/packages/container/libraries/strongly-typed/src/inject.spec.ts b/packages/container/libraries/strongly-typed/src/inject.spec.ts index e0ec9e40..f449dff3 100644 --- a/packages/container/libraries/strongly-typed/src/inject.spec.ts +++ b/packages/container/libraries/strongly-typed/src/inject.spec.ts @@ -4,9 +4,9 @@ import { describe, it } from '@jest/globals'; import 'reflect-metadata'; -import { inject, injectable } from 'inversify'; +import { inject, injectable, multiInject } from 'inversify'; -import type { TypedInject } from './inject'; +import type { TypedInject, TypedMultiInject } from './inject'; describe('@inject', () => { @injectable() @@ -72,4 +72,55 @@ describe('@inject', () => { } Test; }); + + describe('multiInject', () => { + const $multiInject: TypedMultiInject = + multiInject as TypedMultiInject; + + it('strongly types injected properties', () => { + class Test { + @$multiInject('foo') + public foo!: Foo[]; + + @$multiInject('bar') + public readonly bar!: Bar[]; + + @$multiInject('asyncNumber') + public num!: number[]; + + // @ts-expect-error :: expects type Bar + @$multiInject('foo') + public badFoo!: Bar[]; + + // @ts-expect-error :: unknown binding + @$multiInject('unknown') + public unknown!: unknown[]; + } + Test; + }); + + it('strongly types injected constructor parameters', () => { + class Test { + constructor( + @$multiInject('foo') + _foo: Foo[], + + @$multiInject('bar') + private readonly _bar: Bar[], + + @$multiInject('asyncNumber') + _num: number[], + + // @ts-expect-error :: expects type Bar + @$multiInject('foo') + _badFoo: Bar[], + + // @ts-expect-error :: unknown binding + @$multiInject('unknown') + _unknown: unknown[], + ) {} + } + Test; + }); + }); }); diff --git a/packages/container/libraries/strongly-typed/src/inject.ts b/packages/container/libraries/strongly-typed/src/inject.ts index b21c0311..e274178c 100644 --- a/packages/container/libraries/strongly-typed/src/inject.ts +++ b/packages/container/libraries/strongly-typed/src/inject.ts @@ -22,3 +22,9 @@ export type TypedInject = < >( identifier: TKey, ) => TypedDecorator>; + +export type TypedMultiInject = < + TKey extends keyof TBindingMap, +>( + identifier: TKey, +) => TypedDecorator>>;