Need help with babel-plugin-transform-typescript-metadata?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

leonardfactory
139 Stars 7 Forks MIT License 66 Commits 19 Opened issues

Description

Babel plugin to emit decorator metadata like typescript compiler

Services available

!
?

Need anything else?

Contributors list

# 135,855
Objecti...
React
GraphQL
Angular
42 commits
# 172,621
Angular
SQL
graphql...
sql-que...
2 commits
# 731
GitHub
Laravel
rust-la...
wechat-...
1 commit

babel-plugin-transform-typescript-metadata

Travis (.com) Codecov npm

Babel plugin to emit decorator metadata like typescript compiler

Motivation

TypeScript Decorators allows advanced reflection patterns when combined with

Reflect.metadata
output.

Current

@babel/preset-typescript
implementation however just strips all types and does not emit the relative Metadata in the output code.

Since this kind of information is used extensively in libraries like Nest and TypeORM to implement advanced features like Dependency Injection, I've thought it would be awesome to be able to provide the same functionality that TypeScript compiler

experimentalDecorators
and
emitDecoratorMetadata
flags
provide.

This means that code like:

import { Injectable, Inject } from 'some-di-library'; // Just an example
import { MyService } from './MyService';
import { Configuration } from './Configuration';

@Injectable() class AnotherService { @Inject() config: Configuration;

constructor(private service: MyService) {} }

will be interpreted like:

import { MyService } from './MyService';
import { Configuration } from './Configuration';

@Injectable() @Reflect.metadata('design:paramtypes', [MyService]) class AnotherService { @Inject() @Reflect.metadata('design:type', Configuration) config: Configuration;

constructor(private service: MyService) {} }

Parameter decorators

Since decorators in typescript supports also Parameters, this plugin also provides support for them, enabling the following syntax:

@Injectable()
class Some {
  constructor(@Inject() private: SomeService);
}

This will be roughly translated to:

// ...
Inject()(Some.prototype, undefined, 0);

Installation

With npm:

npm install --dev --save babel-plugin-transform-typescript-metadata

or with Yarn:

yarn add --dev babel-plugin-transform-typescript-metadata

Usage

With

.babelrc
:

Note: should be placed before

@babel/plugin-proposal-decorators
.
{
  "plugins": [
    "babel-plugin-transform-typescript-metadata",
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
    ["@babel/plugin-proposal-class-properties", { "loose": true }],
  ],
  "presets": [
    "@babel/preset-typescript"
  ]
}

Usage with InversifyJS

If you are using normal dependency injection letting Inversify create your instances, you should be fine with all kind of decorators.

Instead, if you are using property injection, when the container does not create the instances, you would likely encounter errors since babel decorators are not exactly the same as TypeScript.

You can fix it by enhancing property decorators with the following function:

import getDecorators from 'inversify-inject-decorators';
// setup the container...
let { lazyInject: originalLazyInject } = getDecorators(container);

// Additional function to make properties decorators compatible with babel. function fixPropertyDecorator(decorator: T): T { return ((...args: any[]) => ( target: any, propertyName: any, ...decoratorArgs: any[] ) => { decorator(...args)(target, propertyName, ...decoratorArgs); return Object.getOwnPropertyDescriptor(target, propertyName); }) as any; }

export const lazyInject = fixPropertyDecorator(originalLazyInject);

Current Pitfalls

  • We cannot know if type annotations are just types (i.e.
    IMyInterface
    ) or concrete values (like classes, etc.). In order to resolve this, we emit the following:
    typeof Type === 'undefined' ? Object : Type
    . The code has the advantage of not throwing. If you know a better way to do this, let me know!

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.