我通过下面描述的测试发现,显然,TypeScript 2.6.2要求在new
中实际引用模块之前在require
中使用导入的元素。
以下两段代码,在撰写本文时从官方的TypeScript文档中提取,构成了我正在讨论的测试的基础。
ZipCodeValidator.ts:
export interface StringValidator {
isAcceptable(s: string): boolean;
}
export const numberRegexp = /^[0-9]+$/;
class ZipCodeValidator implements StringValidator {
isAcceptable(s: string) {
return s.length === 5 && numberRegexp.test(s);
}
}
export { ZipCodeValidator };
export { ZipCodeValidator as mainValidator };
SimpleModule.ts:
import { ZipCodeValidator } from "./ZipCodeValidator";
class Test {
constructor(validator: ZipCodeValidator) {
let myValidator = new ZipCodeValidator(); // <- NOTE THIS LINE.
let x = 1;
}
}
tsconfig.json:
{
"compilerOptions": {
"declaration": false,
"emitDecoratorMetadata": false,
"experimentalDecorators": false,
"module": "CommonJS",
"moduleResolution": "classic",
"noFallthroughCasesInSwitch": false,
"noImplicitAny": false,
"noImplicitReturns": false,
"outDir": "dist/scripts",
"removeComments": false,
"sourceMap": false,
"strictNullChecks": false,
"target": "es3"
},
"include": [
"app/ts/**/*.ts"
],
"compileOnSave": true,
"buildOnSave": true
}
Transpiled ZipCodeValidator.js:
"use strict";
exports.__esModule = true;
exports.numberRegexp = /^[0-9]+$/;
var ZipCodeValidator = /** @class */ (function () {
function ZipCodeValidator() {
}
ZipCodeValidator.prototype.isAcceptable = function (s) {
return s.length === 5 && exports.numberRegexp.test(s);
};
return ZipCodeValidator;
}());
exports.ZipCodeValidator = ZipCodeValidator;
exports.mainValidator = ZipCodeValidator;
Transpiled SimpleModule.js(突出显示的行保持原样 - 可以看到有一个require
调用):
"use strict";
exports.__esModule = true;
var ZipCodeValidator_1 = require("./ZipCodeValidator");
var Test = /** @class */ (function () {
function Test(validator) {
var myValidator = new ZipCodeValidator_1.ZipCodeValidator();
var x = 1;
}
return Test;
}());
Transpiled SimpleModule.js(突出显示的行已注释掉 - require
调用已消失):
"use strict";
exports.__esModule = true;
var Test = /** @class */ (function () {
function Test(validator) {
//let myValidator = new ZipCodeValidator();
var x = 1;
}
return Test;
}());
对我来说,这是有问题的,因为我已经将AngularJs应用程序转换为TypeScript而我使用的是模块而不是命名空间,因为我想使用Webpack在每个模块中构建可重用的组件。我没有new
件事:AngularJs为我做了这件事。我转换为使用TS编写的模块的目的是最终获得快速启动时间和动态模块加载的好处。
因此,即使require
存在,但已编译的JS代码也没有exports
s。由Webpack构建的bundle.js文件太小,实际上不包含所需的所有内容。
是否有办法或设置让已存在的import {ServiceXYZ} from "./ServiceXYZ"
TypeSscript说明变为适当的require
来电?
答案 0 :(得分:1)
使require
出现在生成代码中的唯一方法是在运行时实际使用一些导入的值,可以是new
,也可以是代码中的其他方式。
TypeScript documentation says:
编译器检测是否在发出的模块中使用了每个模块 JavaScript的。如果模块标识符仅用作类型的一部分 注释,永远不作为表达,然后不需要调用 为该模块发射。
所以,这是记录的功能,有些人是relying upon it,我担心没有简单的方法。
答案 1 :(得分:1)
此行为为specific to TypeScript imports。它删除了可能未使用的代码片段,并且在大多数情况下都是受欢迎的。
只要ServiceXYZ
未使用,
import {ServiceXYZ} from "./ServiceXYZ"
将被忽略。如果可能使用模块导出,但它也提供副作用并且应该以任何方式导入,则应重复导入:
import "./ServiceXYZ";
import {ServiceXYZ} from "./ServiceXYZ"