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

@babel/typescript removed types which prevents decorator metadata from being emitted #9681

Open
elderapo opened this Issue Mar 14, 2019 · 4 comments

Comments

Projects
None yet
3 participants
@elderapo
Copy link

elderapo commented Mar 14, 2019

Bug Report

Current Behavior
It logs couldn't get the type :(.

Input Code

import "reflect-metadata";

const logType = (target: any, key: string): void => {
  const type = Reflect.getMetadata("design:type", target, key);
  if (!type) {
    console.log("couldn't get the type :(");
    return;
  }
  console.log(`${key} type: ${type.name}`);
};

class Demo {
  @logType
  public someProperty: number = 0;
}

new Demo();

Expected behavior/code
It should log someProperty type: Number.

Babel Configuration (.babelrc)

{
  "presets": ["@babel/env", "@babel/typescript"],
  "plugins": [
    ["@babel/plugin-proposal-decorators", { "decoratorsBeforeExport": true }],
    "@babel/proposal-class-properties",
    "@babel/proposal-object-rest-spread"
  ]
}

Environment

  • Babel version(s): 7.2.0
  • Node/npm version: doesn't matter
  • OS: doesn't matter
  • Monorepo: no
  • How you are using Babel: babel-node/cli

Possible Solution
There is a package babel-decorators-metadata which tries to solve this issue but at the same time breaks some stuff. There is also a question on stackoverflow regarding this issue.

Additional context/Screenshots
@babel/typescript removes TypeScript type definitions before compilation process which causes packages such as reflect-metadata to not work correctly.

@elderapo elderapo added the i: bug label Mar 14, 2019

@babel-bot

This comment has been minimized.

Copy link
Collaborator

babel-bot commented Mar 14, 2019

Hey @elderapo! We really appreciate you taking the time to report an issue. The collaborators
on this project attempt to help as many people as possible, but we're a limited number of volunteers,
so it's possible this won't be addressed swiftly.

If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack
community
that typically always has someone willing to help. You can sign-up here
for an invite.

@nicolo-ribaudo

This comment has been minimized.

Copy link
Member

nicolo-ribaudo commented Mar 14, 2019

Why do you expect the type annotation to be stored as a metadata? No one of typescript, decorators or class fields does that.

Anyway, if you want to keep types you should remove the typescript preset.

@elderapo

This comment has been minimized.

Copy link
Author

elderapo commented Mar 14, 2019

Because there is an emitDecoratorMetadata set to true in the tsconfig.json. For comparison, the same code running with ts-node correctly emits decorators metadata:

elderapo@ziemniak:/tmp/babel-typescript-reflect-metadata-bug$ yarn start-ts-node
yarn run v1.13.0
$ ts-node ./src/index.ts
someProperty type: Number
Done in 0.82s.

I don't understand how removing the typescript preset would solve the issue 🤔?

@nicolo-ribaudo

This comment has been minimized.

Copy link
Member

nicolo-ribaudo commented Mar 14, 2019

Because there is an emitDecoratorMetadata set to true in the tsconfig.json

Oh ok. Babel doesn't load the tsconfig.json file, but it transforms TS as if you were transforming it only with the isolatedModules: true option.

I suggest that you use something like this to define those metadata:

import "reflect-metadata";

const logType = (target: any, key: string): void => {
  const type = Reflect.getMetadata("design:type", target, key);
  if (!type) {
    console.log("couldn't get the type :(");
    return;
  }
  console.log(`${key} type: ${type.name}`);
};

class Demo {
  @logType
  @Reflect.metadata("design:type", Number)
  public someProperty: number = 0;
}

new Demo();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.