TypeScript: Avoid require statements in compiled JavaScript

旧街凉风 提交于 2020-01-04 05:17:09

问题


In my TypeScript code I am using a third-party library called bunyan like so:

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

Because TypeScript cannot resolve the variable bunyan, I do this to make the TypeScript compiler work:

import * as bunyan from "bunyan";

Unfortunately this causes the following JavaScript output:

var bunyan = require("bunyan");

The require statement will not work in the browser (when not using a requirejs implementation), so I will receive: Uncaught ReferenceError: require is not defined.

Actually I don't need the require statement in my compiled JavaScript because there is a bunyan.min.js (browserified version) which I can use for the browser. But how can I avoid the bunyan import in my TypeScript code without having the TypeScript compiler complaining about an unknown reference?

I am using TypeScript 1.8 and this is my TypeScript compiler configuration:

tsconfig.json

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

回答1:


You should use declare to declare a module for bunyan with Logger and createLogger.

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

I would recommend using a typings declaration file like the one found here so you get the full benefit of TypeScript :)




回答2:


I found out that there are two things that come into play:

  1. Package reference
  2. Type declaration

Explanation

In my initial code I imported bunyan which helped the TypeScript compiler to find bunyan's declaration. With the assignment of private logger: bunyan.Logger I also forced type safety on my logger variable.

To get rid off the bunyan reference (to also get rid off the compiled var bunyan = require("bunyan"); code) I needed to trick the compiler.

The TS compiler can be cheated by removing the import and telling TypeScript that there is something (any) out in the wild which is named bunyan. This can be done by writing:

declare var bunyan: any;

Because the TS compiler is tricked there is no way for it to guarantee type safety anymore, so the specific type from the logger variable needs to be removed and it's declaration must look like the following statement:

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

This bring us to the following solution:

Before

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

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

After

// Package reference
declare var bunyan: any; 

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

Thanks James Monger for making this clear to me.



来源:https://stackoverflow.com/questions/38127953/typescript-avoid-require-statements-in-compiled-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!