Closed user753 closed 5 years ago
Do you have the following in your tsconfig.json
?
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
@Xapphire13 Yes
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve"
},
"include": [
"src"
]
}
You have an import "reflect-metadata";
before your code executes right?
@Xapphire13 Yes, otherwize it would be tsyringe requires a reflect polyfill. Please add 'import "reflect-metadata"' to the top of your entry point.
.
Did you try to use tsyringe with create-react-app?
No I haven't tried that yet. The error about polyfill is relatively new and you never specified the version you're using, I just wanted to cover all bases.
I just created a react-app using create-react-app --typescript
, added your sample code and got the same issue.
I then did some digging and this is because decorators are explicitly disabled for create-react-app
apps.
In order to use decorators you must eject your app first.
@Xapphire13 They support decorators for typescript https://github.com/facebook/create-react-app/releases/tag/v2.1.1
function foo() {
console.log("f(): evaluated");
return function (target:any , propertyKey: string, descriptor: PropertyDescriptor) {
console.log("f(): called");
}
}
class Test {
@foo()
method() {}
}
new Test().method()
Works just fine.
The next thing would be the babel config that create-react-app
uses, see: https://github.com/rbuckton/reflect-metadata/issues/104
For some reason all the type info is stripped. I personally use tsyringe
in an ejected app with no issues (I don't use babel in my app)
Ok. I think it will be solved with this https://github.com/facebook/create-react-app/issues/6388
If you stumble upon this issue outside of React, be sure that the service you're resolving has a @injectable()
decorator.
hmmm... getting this in a jest test...
import { ApolloServerTestClient } from 'apollo-server-testing';
import 'reflect-metadata';
import testContext from '../test-fixtures/testContext';
import { Beans } from '../types/Beans';
test('version query', async() => {
const { query } = await testContext()
.resolve<Promise<ApolloServerTestClient>>(Beans.APOLLO_TEST_CLIENT);
const res = await query({ query: '{ version }' });
expect(res.data).toEqual({ version: 'dev' });
});
it's complaining at test
Error: Failed: "TypeInfo not known for function Object() { [native code] }"
Error:
at Env.it (/Users/calebcushing/IdeaProjects/service-graph/node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:91:24)
at it (/Users/calebcushing/IdeaProjects/service-graph/node_modules/jest-jasmine2/build/jasmine/jasmineLight.js:93:21)
at Object.<anonymous> (/Users/calebcushing/IdeaProjects/service-graph/src/__tests__/VersionTest.ts:6:1)
at Runtime._execModule (/Users/calebcushing/IdeaProjects/service-graph/node_modules/jest-runtime/build/index.js:867:68)
at Runtime._loadModule (/Users/calebcushing/IdeaProjects/service-graph/node_modules/jest-runtime/build/index.js:577:12)
at Runtime.requireModule (/Users/calebcushing/IdeaProjects/service-graph/node_modules/jest-runtime/build/index.js:433:10)
at /Users/calebcushing/IdeaProjects/service-graph/node_modules/jest-jasmine2/build/index.js:202:13
at Generator.next (<anonymous>)
at asyncGeneratorStep (/Users/calebcushing/IdeaProjects/service-graph/node_modules/jest-jasmine2/build/index.js:27:24)
at _next (/Users/calebcushing/IdeaProjects/service-graph/node_modules/jest-jasmine2/build/index.js:47:9)
I'm sure I've done something wrong... but this feels like a red herring, like where is the thing that's really wrong?
I ended up walking through my "resolutions" until I found the ones, failing, they needed an @inject("tag")
but, this is an especially terrible exception, because it doesn't come from the attempt to resolve, and it doesn't tell me what it can't inject or what class it's trying to inject to, or even which class it's ultimately trying to resolve.
could we reopen this for better exceptions?
I opened a new issue #70
Anyone stumbling over this issue, check if you imported the class via import type
. TypeScript does not catch, that the type is being used as a value here!
I had other types imported from a file when I auto-imported the class from it (which added it to the import type
definition).
Maybe this specific problem could be solved with an eslint rule or something.
For those struggling with this error in create-react-app typescript, the issue doesn't appear to be resolved against the latest version.
As noted above, CRA supports ts decorators (test here) and emitting decorator metadata.
The issue is that babel still strips this metadata out, where babel is used in the web bundle and jest by CRA. See these issues for context: https://github.com/facebook/create-react-app/issues/6388 (doesn't appear to have solved it) https://github.com/babel/babel/issues/9681
I solved this in my case without ejecting by using craco to configure babel to use babel-plugin-transform-typescript-metadata
I had this same issue with Expo, this solution worked for me: https://github.com/inversify/InversifyJS/issues/1007#issuecomment-490835213
Had this issue on React Native. I had some decorated classes that depended on objects outside the class. Refactoring those fixed the issue.
I have this same issue with Vite3, is this library not compatible with Vite?
I have this same issue with Vite3, is this library not compatible with Vite?
Vite uses esbuild under the hood which doesn't emit decorator metadata.
There are a few options to work around this in practice, all involving transpiling modules with something other than esbuild like babel or swc.
In my case, I didn't want to drag in any additional dependencies so I wrote a custom vite plugin that transpiles modules that use decorators with the vanilla typescript compiler via the programmatic API.
If you're running into this issue with Jest, ensure you have the following plugins:
transform: {
// Use babel-jest to transpile tests with the next/babel preset
// https://jestjs.io/docs/configuration#transform-objectstring-pathtotransformer--pathtotransformer-object
"^.+\\.(js|jsx|ts|tsx)$": [
"babel-jest",
{
presets: ["next/babel"],
plugins: [
["@babel/plugin-proposal-decorators", { legacy: true }], //THIS ONE
"babel-plugin-transform-typescript-metadata", // AND THIS ONE
],
},
],
},
I created a react app with --typescript install tsyringe and reflect-metadata and got this error