12

I'm trying to use the code in this SO answer. It uses Reflect. Here's a copy:

export function CustomComponent(annotation: any) {
  return function (target: Function) {
    var parentTarget = Object.getPrototypeOf(target.prototype).constructor;
    var parentAnnotations = Reflect.getMetadata('annotations', parentTarget);

    var parentAnnotation = parentAnnotations[0];
    Object.keys(parentAnnotation).forEach(key => {
      if (isPresent(parentAnnotation[key])) {
        annotation[key] = parentAnnotation[key];
      }
    });
    var metadata = new ComponentMetadata(annotation);

    Reflect.defineMetadata('annotations', [ metadata ], target);
  }
}

First, I got these two errors:

Property 'getMetadata' does not exist on type 'typeof Reflect'.
Property 'defineMetadata' does not exist on type 'typeof Reflect'.

Then I ran npm install reflect-metadata, but I don't know how to use it.

import { Reflect } from reflect-metadata;

Module '".../node_modules/reflect-metadata/index"' has no exported
member 'Reflect'.

Or

import { Reflect } from 'reflect-metadata/Reflect';

Cannot find name 'Record'. 
Type '{}' is not assignable to type 'V'.
File '.../node_modules/reflect-metadata/Reflect.ts' is not a module.

Or

import "reflect-metadata"

rollup: Treating 'fs' as external dependency 
bundle update failed: Error transforming .../node_modules/typescript/lib/typescript.js
with 'commonjs' plugin: The keyword 'package' is reserved (57066:28) in
.../node_modules/typescript/lib/typescript.js 

Or

var reflect = require("reflect-metadata");

Cannot find name 'require'.

Or

declare var require: any;
var reflect = require("reflect-metadata");
var Reflect = reflect.Reflect;

    rollup: Treating 'fs' as external dependency 
bundle update failed: Error transforming .../node_modules/typescript/lib/typescript.js
with 'commonjs' plugin: The keyword 'package' is reserved (57066:28) in
.../node_modules/typescript/lib/typescript.js

Surely I'm just missing something silly, even a typo. What can I do to use this code?

Community
  • 1
  • 1
jmilloy
  • 7,875
  • 11
  • 53
  • 86

4 Answers4

26

you have to import the type declarations together with the (js) library

npm install reflect-metadata -D

inside your .ts file:

 import "reflect-metadata";
David Dehghan
  • 22,159
  • 10
  • 107
  • 95
hannes neukermans
  • 12,017
  • 7
  • 37
  • 56
11

As of today, @types/reflect-metadata is deprecated since reflect-metadata includes already its own typings.

So, to use them you just need to import the library (Uses the global scope). That's it.

  1. Install it:
    npm install reflect-metadata --save

  2. Import it:
    import 'reflect-metadata';

Gabriel G.
  • 731
  • 9
  • 15
2

Typescript uses a Module loading paradigm that's a bit different than that of JavaScript.

Say you have a module Modulus that defines three classes A, B and C.

import { A } from "Modulus"

will import the class (or function) A from the module Modulus and make it available in your current module. If Typescript finds no export named A in Modulus and error will be thrown.

// Equivalent to the following in JavaScript:
// var ModuleNameOfYourChoice = require("Modulus")

import * as ModuleNameOfYourChoice from "Modulus"

will import all the exports declared within Modulus and make them available to the current module under the name ModuleNameOfYourChoice.

For your code, you need all the exports defined in reflect-metadata module and thus need to import it as

import * as Reflect from "reflect-metadata"

All the best!

Typescript documentation: http://www.typescriptlang.org/docs/handbook/modules.html#import

-1

I found another solution if you can use es7+. So in your tsconfig.json file you need to change only one line. Change assigment of "target" to at least es2017. And that's all now you can use Reflect out of the box. I think it is very good solution because you do not have to care about additional dependencies

Example tsconfig.json

{
  "compilerOptions": {
    "experimentalDecorators": true,
    "outDir": "../dist",
    "module": "umd",
    "target": "es2017",
    "sourceMap": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "removeComments": false,
    "moduleResolution": "node"
  },
  "exclude": [
    "node_modules",
    "bower_components",
    "dist"
  ]
}
Krzysztof Kaczyński
  • 4,412
  • 6
  • 28
  • 51