Skip to content

Commit

Permalink
feat(strongly-typed): add @multiInject() types
Browse files Browse the repository at this point in the history
  • Loading branch information
alecgibson committed Dec 5, 2024
1 parent ad5d964 commit e505894
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .changeset/curly-singers-add.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@inversifyjs/strongly-typed": minor
---

Added `TypedMultiInject`
5 changes: 3 additions & 2 deletions packages/container/libraries/strongly-typed/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<BindingMap>;
export const $multiInject = multiInject as TypedMultiInject<BindingMap>;
```

You can now use this to strongly type injected constructor parameters, or **public** properties:
Expand Down
55 changes: 53 additions & 2 deletions packages/container/libraries/strongly-typed/src/inject.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -72,4 +72,55 @@ describe('@inject', () => {
}
Test;
});

describe('multiInject', () => {
const $multiInject: TypedMultiInject<BindingMap> =
multiInject as TypedMultiInject<BindingMap>;

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;
});
});
});
6 changes: 6 additions & 0 deletions packages/container/libraries/strongly-typed/src/inject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,9 @@ export type TypedInject<TBindingMap extends BindingMap> = <
>(
identifier: TKey,
) => TypedDecorator<Awaited<TBindingMap[TKey]>>;

export type TypedMultiInject<TBindingMap extends BindingMap> = <
TKey extends keyof TBindingMap,
>(
identifier: TKey,
) => TypedDecorator<Array<Awaited<TBindingMap[TKey]>>>;

0 comments on commit e505894

Please sign in to comment.