Basic register throws TypeInfo not known if constructor has parameters
Opened this issue ยท 10 comments
Describe the bug
While doing some unit test to evaluate the library I found that a simple class registration throws TypeInfo not Known only when it has construction parameters. It works when no construction parameters.
I must be missing something, but I already added
- reflect-metadata
- decorators
To Reproduce
- create the following jest unit test
- launch
- line
const papa = container.resolve(Papa);
--> works becausePapa
class has no parameters - line
const foo = container.resolve<Toto>(Toto);
-> fails withTypeInfo not know
- replace
Toto
class constructor with an empty one -> it works
By the way, I also tried having Toto
constructor with only Bar
parameter and still fails (in case primitive type needed to be handled differently)
import 'reflect-metadata';
import { container, injectable } from 'tsyringe';
beforeEach(() => {
container.reset();
container.clearInstances();
});
interface IToto {
getName(): string;
}
@injectable()
class Bar {}
@injectable()
class Papa implements IToto {
getName(): string {
return 'papa';
}
}
@injectable()
class Toto implements IToto {
name: string = 'default';
//constructor() {
constructor(name: string, private value: Bar) {
console.log(`TOTO instance created with name '${name}' and value '${value}'`);
}
public getName(): string {
return this.name;
}
}
describe('tsyringe bug ?', () => {
test('constructor with parameters generates typeInfo not known', () => {
container.registerInstance(Bar, new Bar());
//container.register<IToto>('ITotot', { useToken: Toto });
container.register(Toto, { useClass: Toto });
container.register(Papa, { useClass: Papa });
container.registerInstance(String, 'toto');
const papa = container.resolve(Papa);
const foo = container.resolve<Toto>(Toto);
});
});
Expected behavior
The instruction container.register(Toto, { useClass: Toto });
should be enough to create the related TypeInfo
Version:
"tsyringe": "^4.7.0"
@brunocapdevila Got any solution ?
Any solution?
FWIW, I had this issue, and fixed with 2 changes:
- added
@injectable()
in addition to being registered explicitly withcontainer.register<myInterface>(token, { useClass: myClass })
, and - tsconfig.json was missing
"emitDecoratorMetadata": true
Given everything I've read about TSyringe, the solution is to inject each of your parameters. This sort of makes sense, given that in order for a class to be injectable, TSyringe needs to know how to fulfill each parameter in the constructor. In this case, you'd have to @inject('someThingForName') name: string
etc for each of your parameters.
If you don't want to have the params be injected, you can instead use container.register('TotoClass', {useValue: new Toto(... inject yourself)})
or container.register('TotoClassType', {useValue: Toto})
Terrible decision migrate the company api to use that DI library :\
I am also experiencing the same issue.
When using tsx, this problem occurs:
Example: "exec": "eslint && tsx watch --tsconfig ./tsconfig.json ./src/index.ts"
However, when running with node/esm, it works without any issues.
Example: "exec": "eslint && pnpify node --import './loader.mjs' ./src/index.ts"
I am currently investigating the root cause.
I am also experiencing the same issue.
When using tsx, this problem occurs: Example: "exec": "eslint && tsx watch --tsconfig ./tsconfig.json ./src/index.ts"
However, when running with node/esm, it works without any issues. Example: "exec": "eslint && pnpify node --import './loader.mjs' ./src/index.ts"
I am currently investigating the root cause.
Any luck?
Having the same issue running basic example:
import "reflect-metadata";
import { container, injectable } from "tsyringe";
@injectable()
class Foo {}
@injectable()
class Bar {
constructor(public myFoo: Foo) {}
}
const myBar = container.resolve(Bar);
If class has no constructor parameters, it just works.
Anyone can shed some light on it? Thanks a lot!
facing the same issue with tsx, any luck @smpark-dev?
facing the same issue with
tsx
, any luck @smpark-dev?
I discovered that the reason is because of tsx
uses esbuild
under the hood and this makes the project to not support tsyringe
and decorators.