thiagobustamante / typescript-ioc

A Lightweight annotation-based dependency injection container for typescript.
MIT License
526 stars 64 forks source link

Invalid @Inject Decorator declaration on property #68

Open jhd-lego opened 4 years ago

jhd-lego commented 4 years ago

I seem to be hitting an error when I am trying to inject a property on my class.

export class ADFSRepository extends AuthFacade {
  @Inject
  private readonly dataSource: ADALDataSource
}

The injected value is bound, it is an abstract class, and it works perfectly fine if I force the Inject declaration to always go to the property declaration here https://github.com/thiagobustamante/typescript-ioc/blob/623a58abd16403f134e5556b83043123155b695d/src/decorators.ts#L149-L150 The issue seems to be that my args is an array of length 3, where the third argument is an object.

0: AuthFacade {constructor: ƒ, signInWithUsername: ƒ}
1: "dataSource"
2: {configurable: true, enumerable: true, writable: true, initializer: null}
length: 3
aopanasenko commented 3 years ago

The same issue

danielgelling commented 3 years ago

Same issue here 😞 . Any solutions/workarounds?

InsOpDe commented 3 years ago

Looks like youre not using ts-node (or ts-jest) to execute the code.

This could be related to https://github.com/evanw/esbuild/issues/412 and https://github.com/thiagobustamante/typescript-ioc/issues/77

AvetisSargsian commented 2 years ago

Hi, I have the same issue, and I did some experiments. @Inject is not working when the project is compiled with create-react-app (babel...) but if I use pure ts project created with webpack-cli (ts-loader) without babel it works fine.

I have also found some suggestions to add some bubel plugins such as: "plugins": [ "babel-plugin-transform-typescript-metadata", ["@babel/plugin-proposal-decorators", { "legacy": true }] ] but it doesn't help in my case.

SimoneGianni commented 2 years ago

Documentation says that when injecting on a property 2 arguments are given, the class and the property name, and also explains why that is the case IN TYPESCRIPT: https://www.typescriptlang.org/docs/handbook/decorators.html#property-decorators

However, it looks like other interpreters are able to pass also the third parameter. So, to support both cases, the check in decorators.ts line 149 should be different:

if (args.length === 3 && typeof args[2] === 'number') {
  return InjectParamDecorator.apply(this, args);
} else if (args.length >= 2) {
  return InjectPropertyDecorator.apply(this, args);
}
// Case for decorator on a class
throw new TypeError('Invalid @Inject Decorator declaration.');

It would still be missing the case of the decorator used on a method, but would work in react.