Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uncaught TypeInfo not known for function Bar(foo) #29

Closed
user753 opened this issue Apr 4, 2019 · 20 comments
Closed

Uncaught TypeInfo not known for function Bar(foo) #29

user753 opened this issue Apr 4, 2019 · 20 comments
Labels

Comments

@user753
Copy link

user753 commented Apr 4, 2019

I created a react app with --typescript
install tsyringe and reflect-metadata and got this error

Uncaught TypeInfo not known for function Bar(foo)
import {container, injectable} from "tsyringe"

export class Foo {}

@injectable()
export class Bar {
  constructor(public foo: Foo) {}
}

export const myBar = container.resolve(Bar);
@Xapphire13
Copy link
Collaborator

Xapphire13 commented Apr 4, 2019

Do you have the following in your tsconfig.json?

"compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
}

@user753
Copy link
Author

user753 commented Apr 5, 2019

@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"
  ]
}

@Xapphire13
Copy link
Collaborator

You have an import "reflect-metadata"; before your code executes right?

@user753
Copy link
Author

user753 commented Apr 15, 2019

@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?

@Xapphire13
Copy link
Collaborator

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.

@Xapphire13
Copy link
Collaborator

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.

@user753
Copy link
Author

user753 commented Apr 16, 2019

@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.

@Xapphire13
Copy link
Collaborator

The next thing would be the babel config that create-react-app uses, see: rbuckton/reflect-metadata#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)

@MeltingMosaic MeltingMosaic reopened this Apr 16, 2019
@user753
Copy link
Author

user753 commented Apr 17, 2019

Ok. I think it will be solved with this facebook/create-react-app#6388

@user753 user753 closed this as completed Apr 17, 2019
@perf2711
Copy link

If you stumble upon this issue outside of React, be sure that the service you're resolving has a @injectable() decorator.

@xenoterracide
Copy link
Contributor

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?

@xenoterracide
Copy link
Contributor

xenoterracide commented Dec 16, 2019

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?

@xenoterracide
Copy link
Contributor

I opened a new issue #70

@Lusito
Copy link

Lusito commented Apr 25, 2020

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.

@kmannislands
Copy link

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:
facebook/create-react-app#6388 (doesn't appear to have solved it)
babel/babel#9681

I solved this in my case without ejecting by using craco to configure babel to use babel-plugin-transform-typescript-metadata

@jonatanlins
Copy link

I had this same issue with Expo, this solution worked for me: inversify/InversifyJS#1007 (comment)

@aleksikontkanen
Copy link

Had this issue on React Native. I had some decorated classes that depended on objects outside the class. Refactoring those fixed the issue.

@roddc
Copy link

roddc commented Nov 8, 2022

I have this same issue with Vite3, is this library not compatible with Vite?

@kmannislands
Copy link

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.

@juanvilladev
Copy link

juanvilladev commented Aug 20, 2023

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
        ],
      },
    ],
  },

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests