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

create-react-app@2.1.8 typescript@3.4.1 Reflect.getMetadata("design:type", target, propertyKey) == undefined ? #104

Closed
r1005410078 opened this issue Apr 3, 2019 · 8 comments
Labels

Comments

@r1005410078
Copy link

r1005410078 commented Apr 3, 2019

class Point {
  x!: number;
  y!: number;
}

class Line {
    private _p0!: Point;
    private _p1!: Point;

    @validate
    set p0(value: Point) { this._p0 = value; }
    get p0() { return this._p0; }

    @validate
    set p1(value: Point) { this._p1 = value; }
    get p1() { return this._p1; }
}

function validate<T>(target: any, propertyKey: string, descriptor: TypedPropertyDescriptor<T>) {
    let set = descriptor.set;
    descriptor.set = function (value: T) {
      let type = Reflect.getMetadata("design:type", target, propertyKey);
      console.log(type) // undefined
      if (!(value instanceof type)) {
        throw new TypeError("Invalid type.");
      }
      // set.call(target, value);
    }
}
{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "preserve",
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "resolveJsonModule": true
  },
  "include": [
    "src"
  ]
}
@r1005410078 r1005410078 changed the title create-react-app typescript 3.41 Reflect.getMetadata("design:type", target, propertyKey) == undefined ? create-react-app typescript 3.4.1 Reflect.getMetadata("design:type", target, propertyKey) == undefined ? Apr 3, 2019
@r1005410078 r1005410078 changed the title create-react-app typescript 3.4.1 Reflect.getMetadata("design:type", target, propertyKey) == undefined ? create-react-app@2.1.8 typescript@3.4.1 Reflect.getMetadata("design:type", target, propertyKey) == undefined ? Apr 3, 2019
@magneticflux-
Copy link

I'm having the same issue. It looks like it comes from here facebook/create-react-app#6388 which leads to babel/babel#9681.

Basically, Babel doesn't support emitDecoratorMetadata: https://babeljs.io/docs/en/babel-plugin-transform-typescript#typescript-compiler-options

@kishaningithub
Copy link

Had the same bug. But when i put

import "reflect-metadata";

as the first ever line in index.tsx with the following options in tsconfig.json

    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,

the issue was solved

@liuxinya
Copy link

liuxinya commented Apr 2, 2020

我是这样处理的...

    1. config-overrides.js 中开启.babelrc
const { useBabelRc } = require('customize-cra');

module.exports = override(
    useBabelRc()
);
    1. .babelrc中添加配置
{
    "plugins": [
      "babel-plugin-transform-typescript-metadata",
      ["@babel/plugin-proposal-decorators", { "legacy": true }],
      ["@babel/plugin-proposal-class-properties", { "loose": true }]
    ],
    "presets": [
      "@babel/preset-typescript"
    ]
}
    1. 把配置中需要的包下载一下

试了好多种方法 这种成功了 你试试看

@hanayashiki
Copy link

我是这样处理的...

* 1. config-overrides.js 中开启.babelrc
const { useBabelRc } = require('customize-cra');

module.exports = override(
    useBabelRc()
);
* 1. .babelrc中添加配置
{
    "plugins": [
      "babel-plugin-transform-typescript-metadata",
      ["@babel/plugin-proposal-decorators", { "legacy": true }],
      ["@babel/plugin-proposal-class-properties", { "loose": true }]
    ],
    "presets": [
      "@babel/preset-typescript"
    ]
}
* 1. 把配置中需要的包下载一下

试了好多种方法 这种成功了 你试试看

also good for react native

@Domingowen
Copy link

我是这样处理的...

* 1. config-overrides.js 中开启.babelrc
const { useBabelRc } = require('customize-cra');

module.exports = override(
    useBabelRc()
);
* 1. .babelrc中添加配置
{
    "plugins": [
      "babel-plugin-transform-typescript-metadata",
      ["@babel/plugin-proposal-decorators", { "legacy": true }],
      ["@babel/plugin-proposal-class-properties", { "loose": true }]
    ],
    "presets": [
      "@babel/preset-typescript"
    ]
}
* 1. 把配置中需要的包下载一下

试了好多种方法 这种成功了 你试试看

also good for react native

I try it. it is working for me. Tips: you should import reflect metadata to every file top line
I use react-native framework.

@rezonant
Copy link

rezonant commented Mar 23, 2021

Actually importing reflect-metadata in every file can cause this problem. If there are two different versions of reflect-metadata in your module tree then multiple versions of reflect-metadata may get loaded. If this happens, you may end up with a sort of "split brain" where some metadata is in one version and some is in the other.

Use npm ls reflect-metadata to see if you have multiple versions of reflect-metadata in your project.

Load reflect-metadata only once in the entrypoint file of the project. Do not import (or add a dependency to) reflect-metadata within a library.

@ramanbedi1989
Copy link

Another thing that I had to do to make @liuxinya's answer work for an application running using Metro builder was to start the application using the command npx react-native start --reset-cache. Without it, unnecessary caching of babel steps was leading to the configuration changes not working. Also, the project's babel.config.js was configured as follows:

module.exports =  {
  "plugins": [
    'babel-plugin-transform-typescript-metadata',
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
    ["@babel/plugin-proposal-class-properties", { "loose" : true }]
  ],
  "presets": ["module:metro-react-native-babel-preset"]
}

@rbuckton
Copy link
Owner

Closing this as External as it seems to be an issue with Babel's emit.

Actually importing reflect-metadata in every file can cause this problem. If there are two different versions of reflect-metadata in your module tree then multiple versions of reflect-metadata may get loaded. If this happens, you may end up with a sort of "split brain" where some metadata is in one version and some is in the other.

Use npm ls reflect-metadata to see if you have multiple versions of reflect-metadata in your project.

Load reflect-metadata only once in the entrypoint file of the project. Do not import (or add a dependency to) reflect-metadata within a library.

This should hopefully no longer be an issue as of reflect-metadata@0.2.1 or later as long as the minimum version of any copy of reflect-metadata in your dependencies is at least reflect-metadata@0.1.12 or higher. In 0.1.12, reflect-metadata would no longer overwrite another copy that was present. As of 0.2.1, there is now a shared registry attached to Reflect that multiple copies will register with so that metadata is still reachable.

Also, the API surface of reflect-metadata is unlikely to change, so it should be safe to manually deduplicate multiple instances of the package in your dependency tree. You can use npm ls reflect-metadata to see which different versions are present, and you can use the "overrides" key in package.json to repoint stale dependencies to the more recent version.

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

9 participants