Skip to content

Commit

Permalink
fix: Clarify typing of injectionDecoratorToken and instantiationDecor…
Browse files Browse the repository at this point in the history
…atorToken

- This should help with understanding what they are actually for

Signed-off-by: Sebastian Malton <[email protected]>
  • Loading branch information
Nokel81 committed Apr 5, 2023
1 parent cba95c8 commit cea796b
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 42 deletions.
149 changes: 113 additions & 36 deletions packages/injectable/core/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,24 +96,38 @@ export function getInjectionToken<
id: string;
}): InjectionToken<InjectionInstance, InstantiationParam>;

interface InjectWithoutParameter {
<InjectionInstance>(
key:
| Injectable<InjectionInstance, unknown>
| InjectionToken<InjectionInstance, void>,
): InjectionInstance;
}

interface InjectWithParameter {
<InjectionInstance, InstantiationParam>(
key:
| Injectable<InjectionInstance, unknown, InstantiationParam>
| InjectionToken<InjectionInstance, InstantiationParam>,
param: InstantiationParam,
): InjectionInstance;
}

type Inject = InjectWithoutParameter & InjectWithParameter;
export type InjectWithoutParameter = <InjectionInstance>(
key:
| Injectable<InjectionInstance, unknown>
| InjectionToken<InjectionInstance, void>,
) => InjectionInstance

export type InjectWithParameter = <InjectionInstance, InstantiationParam>(
key:
| Injectable<InjectionInstance, unknown, InstantiationParam>
| InjectionToken<InjectionInstance, InstantiationParam>,
param: InstantiationParam,
) => InjectionInstance;

export type Inject = InjectWithoutParameter & InjectWithParameter;

export type SpecificInjectWithoutParameter<InjectionInstance> = (
key:
| Injectable<InjectionInstance, unknown>
| InjectionToken<InjectionInstance, void>,
) => InjectionInstance;

export type SpecificInjectWithParameter<InjectionInstance, InstantiationParam> = (
key:
| Injectable<InjectionInstance, unknown, InstantiationParam>
| InjectionToken<InjectionInstance, InstantiationParam>,
param: InstantiationParam,
) => InjectionInstance;

export type SpecificInject<InjectionInstance, InstantiationParam> =
InstantiationParam extends void
? SpecificInjectWithoutParameter<InjectionInstance>
: SpecificInjectWithParameter<InjectionInstance, InstantiationParam>;

interface InjectMany {
<InjectionInstance>(
Expand Down Expand Up @@ -191,13 +205,60 @@ export const lifecycleEnum: {

type RegistrationCallback = (injectable: Injectable<any, any, any>) => void;

export type InjectionTargetDecorator<InjectionInstance, InstantiationParam> = {
decorate: (
instantiate: Instantiate<InjectionInstance, InstantiationParam>,
) => Instantiate<InjectionInstance, InstantiationParam>;
export type SpecificInjectionTargetDecorator<
InjectionInstance extends InjectionTokenInstance,
InjectionTokenInstance = InjectionInstance,
InstantiationParam = void,
> = {
decorate: (inject: SpecificInject<InjectionInstance, InstantiationParam>) => SpecificInject<InjectionInstance, InstantiationParam>;
target:
| InjectionToken<InjectionInstance, InstantiationParam>
| Injectable<InjectionInstance, InjectionTokenInstance, InstantiationParam>;
}

export type GeneralInjectionTargetDecorator = {
decorate: (inject: SpecificInject<unknown, unknown>) => SpecificInject<unknown, unknown>;
};

export type InstantiationTargetDecorator<
export type InjectionTargetDecorator<
InjectionInstance extends InjectionTokenInstance,
InjectionTokenInstance = InjectionInstance,
InstantiationParam = void,
> =
| GeneralInjectionTargetDecorator
| SpecificInjectionTargetDecorator<
InjectionInstance,
InjectionTokenInstance,
InstantiationParam
>;

export interface CreateInjectionTargetDecorator {
<
InjectionInstance extends InjectionTokenInstance,
InjectionTokenInstance = InjectionInstance,
InstantiationParam = void,
>(
desc: SpecificInjectionTargetDecorator<
InjectionInstance,
InjectionTokenInstance,
InstantiationParam
>
): SpecificInjectionTargetDecorator<
InjectionInstance,
InjectionTokenInstance,
InstantiationParam
>;
(desc: GeneralInjectionTargetDecorator): GeneralInjectionTargetDecorator;
}

export const createInjectionTargetDecorator: CreateInjectionTargetDecorator;

export const injectionDecoratorToken: InjectionToken<
InjectionTargetDecorator<any, any, any>,
void
>;

export type SpecificInstantiationTargetDecorator<
InjectionInstance extends InjectionTokenInstance,
InjectionTokenInstance = InjectionInstance,
InstantiationParam = void,
Expand All @@ -211,26 +272,42 @@ export type InstantiationTargetDecorator<
| Injectable<InjectionInstance, InjectionTokenInstance, InstantiationParam>;
};

export const createInstantiationTargetDecorator: <
export type GeneralInstantiationTargetDecorator = {
decorate: (
instantiate: Instantiate<unknown, unknown>,
) => Instantiate<unknown, unknown>;
};

export type InstantiationTargetDecorator<
InjectionInstance extends InjectionTokenInstance,
InjectionTokenInstance = InjectionInstance,
InstantiationParam = void,
>(
desc: InstantiationTargetDecorator<
> =
| GeneralInstantiationTargetDecorator
| SpecificInstantiationTargetDecorator<
InjectionInstance,
InjectionTokenInstance,
InstantiationParam
>,
) => InstantiationTargetDecorator<
InjectionInstance,
InjectionTokenInstance,
InstantiationParam
>;
>;

export const injectionDecoratorToken: InjectionToken<
InjectionTargetDecorator<unknown, unknown>,
void
>;
export interface CreateInstantiationTargetDecorator {
<
InjectionInstance extends InjectionTokenInstance,
InjectionTokenInstance = InjectionInstance,
InstantiationParam = void,
>(desc: SpecificInstantiationTargetDecorator<
InjectionInstance,
InjectionTokenInstance,
InstantiationParam
>): SpecificInstantiationTargetDecorator<
InjectionInstance,
InjectionTokenInstance,
InstantiationParam
>;
(desc: GeneralInstantiationTargetDecorator): GeneralInstantiationTargetDecorator;
}

export const createInstantiationTargetDecorator: CreateInstantiationTargetDecorator;

export const instantiationDecoratorToken: InjectionToken<
InstantiationTargetDecorator<any, any, any>,
Expand Down
1 change: 1 addition & 0 deletions packages/injectable/core/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import isInjectable from './src/getInjectable/isInjectable';
import isInjectionToken from './src/getInjectionToken/isInjectionToken';

export { createInstantiationTargetDecorator } from './src/dependency-injection-container/createInstantiationTargetDecorator';
export { createInjectionTargetDecorator } from './src/dependency-injection-container/createInjectionTargetDecorator';

export {
deregistrationCallbackToken,
Expand Down
50 changes: 44 additions & 6 deletions packages/injectable/core/index.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ import {
Instantiate,
Injectable,
injectionDecoratorToken,
Inject,
createInjectionTargetDecorator,
SpecificInject,
InjectionToken,
} from '.';

const di = createContainer('some-container');
Expand Down Expand Up @@ -66,7 +70,7 @@ const decoratorForInjectable = getInjectable({
injectionToken: instantiationDecoratorToken,
});

// given injectable with instantiation paramater and decorator targeting the injectable, typing is ok
// given injectable with instantiation parameter and decorator targeting the injectable, typing is ok
const someParameterInjectableToBeDecorated = getInjectable({
id: 'some-parameter-injectable-to-be-decorated',
instantiate: (di, parameter: number) => `some-instance-${parameter}`,
Expand Down Expand Up @@ -97,18 +101,52 @@ const decoratorForParameterInjectable = getInjectable({
injectionToken: instantiationDecoratorToken,
});

const decoratorWithoutTargetInjectable = getInjectable({
id: 'decorator-without-target',

instantiate: () =>
createInstantiationTargetDecorator({
decorate: toBeDecorated => (di, param) => {
expectType<unknown>(param);
expectType<Instantiate<unknown, unknown>>(toBeDecorated);

const instance = toBeDecorated(di, param);

return instance;
},
}),

injectionToken: instantiationDecoratorToken,
});

const decoratorForInjectionParameterInjectable = getInjectable({
id: 'decorator-for-parameter-injectable',

instantiate: () => ({
decorate: toBeDecorated => (di, param) => {
instantiate: () => createInjectionTargetDecorator({
decorate: injectionToBeDecorated => (key, param) => {
expectType<SpecificInject<unknown, unknown>>(injectionToBeDecorated);
expectType<Injectable<unknown, unknown, unknown> | InjectionToken<unknown, unknown>>(key);
expectType<unknown>(param);
expectType<Instantiate<unknown, unknown>>(toBeDecorated);

const instance = toBeDecorated(di, param);
return injectionToBeDecorated(key, param);
},
}),

injectionToken: injectionDecoratorToken,
});

const decoratorForSpecificInjectionParameterInjectable = getInjectable({
id: 'decorator-for-parameter-injectable',

instantiate: () => createInjectionTargetDecorator({
decorate: injectionToBeDecorated => (key, param) => {
expectType<SpecificInject<string, number>>(injectionToBeDecorated);
expectType<Injectable<string, unknown, number> | InjectionToken<string, number>>(key);
expectType<number>(param);

return instance;
return injectionToBeDecorated(key, param);
},
target: someParameterInjectableToBeDecorated,
}),

injectionToken: injectionDecoratorToken,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const createInjectionTargetDecorator = desc => desc;

0 comments on commit cea796b

Please sign in to comment.