Skip to content

Commit

Permalink
fix(di): preserve original metadata on @Inject decorator
Browse files Browse the repository at this point in the history
Closes #2399
  • Loading branch information
omermorad authored and Romakita committed Aug 15, 2023
1 parent 1fc62a0 commit 1a04809
Show file tree
Hide file tree
Showing 7 changed files with 19 additions and 8 deletions.
2 changes: 1 addition & 1 deletion packages/di/jest.config.js
Expand Up @@ -6,7 +6,7 @@ module.exports = {
coverageThreshold: {
global: {
statements: 98.81,
branches: 96.71,
branches: 96.54,
lines: 98.81,
functions: 98.32
}
Expand Down
4 changes: 2 additions & 2 deletions packages/di/src/common/decorators/inject.spec.ts
Expand Up @@ -67,7 +67,7 @@ describe("@Inject()", () => {
class MyService1 implements InterfaceGroup {
readonly type: string = "service1";

constructor(@Inject(InjectorService) readonly injector: InjectorService) {}
constructor(@Inject(InjectorService) readonly injector: any) {}
}

@Injectable({
Expand All @@ -76,7 +76,7 @@ describe("@Inject()", () => {
class MyService2 implements InterfaceGroup {
readonly type: string = "service2";

constructor(@Inject(InjectorService) readonly injector: InjectorService) {}
constructor(@Inject(InjectorService) readonly injector: any) {}
}

const TokenAsync = Symbol.for("MyService2");
Expand Down
6 changes: 3 additions & 3 deletions packages/di/src/common/decorators/inject.ts
Expand Up @@ -3,6 +3,7 @@ import {DI_PARAM_OPTIONS, INJECTABLE_PROP} from "../constants/constants";
import {InvalidPropertyTokenError} from "../errors/InvalidPropertyTokenError";
import type {InjectablePropertyOptions} from "../interfaces/InjectableProperties";
import {TokenProvider} from "../interfaces/TokenProvider";
import {getConstructorDependencies, setConstructorDependencies} from "../utils/getConstructorDependencies";

export function injectProperty(target: any, propertyKey: string, options: Partial<InjectablePropertyOptions>) {
Store.from(target).merge(INJECTABLE_PROP, {
Expand Down Expand Up @@ -39,18 +40,17 @@ export function Inject(token?: TokenProvider | (() => TokenProvider), onGet = (b
switch (bindingType) {
case DecoratorTypes.PARAM_CTOR:
if (token) {
const paramTypes = Metadata.getParamTypes(target, propertyKey);
const paramTypes = getConstructorDependencies(target);
const type = paramTypes[descriptor as number];

paramTypes[descriptor as number] = type === Array ? [token] : token;

Metadata.setParamTypes(target, propertyKey!, paramTypes);
setConstructorDependencies(target, paramTypes);
}
break;

case DecoratorTypes.PROP:
const useType = token || Metadata.getType(target, propertyKey);
const originalType = Metadata.getType(target, propertyKey);

if (useType === Object) {
throw new InvalidPropertyTokenError(target, String(propertyKey));
Expand Down
2 changes: 1 addition & 1 deletion packages/di/src/common/domain/Provider.ts
@@ -1,4 +1,4 @@
import {classOf, getClassOrSymbol, isClass, methodsOf, nameOf, Store, Type} from "@tsed/core";
import {classOf, getClassOrSymbol, isClass, Metadata, methodsOf, nameOf, Store, Type} from "@tsed/core";
import {ProviderOpts} from "../interfaces/ProviderOpts";
import {TokenProvider} from "../interfaces/TokenProvider";
import {ProviderScope} from "./ProviderScope";
Expand Down
1 change: 1 addition & 0 deletions packages/di/src/common/index.ts
Expand Up @@ -51,4 +51,5 @@ export * from "./services/InjectorService";
export * from "./utils/colors";
export * from "./utils/createContainer";
export * from "./utils/getConfiguration";
export * from "./utils/getConstructorDependencies";
export * from "./utils/resolveControllers";
3 changes: 2 additions & 1 deletion packages/di/src/common/services/InjectorService.ts
Expand Up @@ -33,6 +33,7 @@ import {ResolvedInvokeOptions} from "../interfaces/ResolvedInvokeOptions";
import {TokenProvider} from "../interfaces/TokenProvider";
import {GlobalProviders} from "../registries/GlobalProviders";
import {createContainer} from "../utils/createContainer";
import {getConstructorDependencies} from "../utils/getConstructorDependencies";
import {resolveControllers} from "../utils/resolveControllers";
import {DIConfiguration} from "./DIConfiguration";

Expand Down Expand Up @@ -701,7 +702,7 @@ export class InjectorService extends Container {
};
} else {
// useClass
deps = deps || Metadata.getParamTypes(provider.useClass);
deps = deps || getConstructorDependencies(provider.useClass);
construct = (deps: TokenProvider[]) => new provider.useClass(...deps);
}

Expand Down
9 changes: 9 additions & 0 deletions packages/di/src/common/utils/getConstructorDependencies.ts
@@ -0,0 +1,9 @@
import {Metadata} from "@tsed/core";

export function getConstructorDependencies(target: any) {
return [...(Metadata.get("override:ctor:design:paramtypes", target, undefined) || Metadata.getParamTypes(target) || [])];
}

export function setConstructorDependencies(target: any, deps: any[]) {
Metadata.set("override:ctor:design:paramtypes", deps, target);
}

0 comments on commit 1a04809

Please sign in to comment.