TypeScript:避免在已编译的 JavaScript 中使用 require 语句

TypeScript: Avoid require statements in compiled JavaScript

在我的 TypeScript 代码中,我使用了一个名为 bunyan 的第三方库,如下所示:

private logger: bunyan.Logger = bunyan.createLogger({name: "MyClass"});

因为 TypeScript 无法解析变量 bunyan,我这样做是为了让 TypeScript 编译器工作:

import * as bunyan from "bunyan";

不幸的是,这会导致以下 JavaScript 输出:

var bunyan = require("bunyan");

require 语句在浏览器中不起作用(当不使用 requirejs 实现时),因此我将收到:Uncaught ReferenceError: require is not defined.

实际上我编译的 JavaScript 中不需要 require 语句,因为有一个 bunyan.min.js(浏览器版本)我可以用于浏览器。但是,如何在 TypeScript 编译器不抱怨未知引用的情况下避免在我的 TypeScript 代码中导入 bunyan?

我正在使用 TypeScript 1.8,这是我的 TypeScript 编译器配置:

tsconfig.json

{
  "compilerOptions": {
    "module": "commonjs",
    "moduleResolution": "node",
    "noEmitOnError": true,
    "noImplicitAny": false,
    "removeComments": true,
    "target": "es5"
  },
  "exclude": [
    "node_modules",
    "typings/browser",
    "typings/browser.d.ts"
  ]
}

您应该使用 declarebunyanLoggercreateLogger 声明一个模块。

declare module bunyan {
    export interface Logger {
        info(message: string): any;
        warn(message: string): any;
    }

    export function createLogger(options: any): Logger;
};

class MyClass {
    private logger: bunyan.Logger = bunyan.createLogger({name: "MyClass"});
}

我建议使用像 the one found here 这样的类型声明文件,这样您就可以充分利用 TypeScript :)

我发现有两件事在起作用:

  1. 包参考
  2. 类型声明

说明

在我的初始代码中,我导入了 bunyan,这有助于 TypeScript 编译器找到 bunyan 的声明。通过分配 private logger: bunyan.Logger 我还对我的 logger 变量强制类型安全。

为了摆脱 bunyan 引用(同时摆脱编译的 var bunyan = require("bunyan"); 代码)我需要欺骗编译器。

TS 编译器可以通过删除 import 并告诉 TypeScript 有一些东西(any)在野外被命名为 bunyan。这可以通过写来完成:

declare var bunyan: any;

因为 TS 编译器被欺骗了,它无法再保证类型安全,所以需要从 logger 变量中删除特定类型,并且它的声明必须类似于以下语句:

private logger: any = bunyan.createLogger({name: "MyClass"});

这给我们带来了以下解决方案:

之前

// Package reference
import * as bunyan from "bunyan"; 

// Type declaration
private logger: bunyan.Logger = bunyan.createLogger({name: "MyClass"});

之后

// Package reference
declare var bunyan: any; 

// Type declaration
private logger: any = bunyan.createLogger({name: "MyClass"});

感谢 James Monger 让我明白这一点。