【问题标题】:How to import/use Reflect in typescript如何在打字稿中导入/使用反射
【发布时间】:2017-05-07 08:24:48
【问题描述】:

我正在尝试使用this SO answer 中的代码。它使用反射。这是一个副本:

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);
  }
}

首先,我得到了这两个错误:

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

然后我跑了npm install reflect-metadata,但是不知道怎么用。

import { Reflect } from reflect-metadata;

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

或者

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.

或者

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 

或者

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

Cannot find name 'require'.

或者

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

当然,我只是错过了一些愚蠢的东西,甚至是一个错字。我该怎么做才能使用此代码?

【问题讨论】:

    标签: javascript node.js typescript


    【解决方案1】:

    如果你可以使用 es7+,我找到了另一个解决方案。因此,在您的tsconfig.json 文件中,您只需更改一行。将 "target" 的分配至少更改为 es2017。这就是现在您可以立即使用Reflect 的全部内容。我认为这是一个很好的解决方案,因为您不必关心额外的依赖项

    示例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"
      ]
    }
    

    【讨论】:

    【解决方案2】:

    您必须将类型声明与 (js) 库一起导入

    npm install reflect-metadata -D
    

    在您的 .ts 文件中:

     import "reflect-metadata";
    

    【讨论】:

    • 谢谢,捆绑更新失败错误是别的。
    • 导入“反射元数据”;导致 eslint 抱怨“应该分配导入的模块”。这不是一个好的编码风格。
    • isPresent() 呢?
    • function isPresent(obj: any): boolean { return obj !== undefined && obj !== null; }
    【解决方案3】:

    截至今天,@types/reflect-metadata 已被弃用,因为 reflect-metadata 已包含其自己的类型。

    因此,要使用它们,您只需要导入库(使用全局范围)。就是这样。

    1. 安装它:
      npm install reflect-metadata --save

    2. 导入:
      import 'reflect-metadata';

    【讨论】:

      【解决方案4】:

      Typescript 使用与 JavaScript 有点不同的模块加载范例。

      假设您有一个模块Modulus,它定义了三个类ABC

      import { A } from "Modulus"
      

      将从模块Modulus 导入类(或函数)A 并使其在您当前的模块中可用。如果 Typescript 在 Modulus 中找不到名为 A 的导出,则会抛出错误。

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

      将导入Modulus 中声明的所有导出,并以名称ModuleNameOfYourChoice 将它们提供给当前模块。

      对于您的代码,您需要在 reflect-metadata 模块中定义的所有导出,因此需要将其导入为

      import * as Reflect from "reflect-metadata"
      

      一切顺利!

      打字稿文档:http://www.typescriptlang.org/docs/handbook/modules.html#import

      【讨论】:

        猜你喜欢
        • 2021-04-21
        • 2020-12-03
        • 2022-07-28
        • 2017-07-31
        • 2021-07-23
        • 2020-04-18
        • 1970-01-01
        • 2023-04-04
        • 2018-10-21
        相关资源
        最近更新 更多