假设我有两个文件,A.js和B.js.两者都需要像这样相互引用。
A.js
import { B } from "b"
export class A {
constructor(public name: string) {}
}
let b = new B();
b.print(new A("This is a random name"));
B.js
import { A } from "a"
export class B {
print(a: A) {
console.log(a.name);
}
}
上面的示例将创建一个循环引用,该引用当前在我正在使用的JavaScript运行时中不起作用。文件B.js实际上只需要类型信息,而不是实际的导出对象)。我希望A.js中的类型得到静态类型检查。这可能吗?
您无需执行任何特殊操作即可从模块a
中仅导入类型信息。
打字稿会为你做 - 如果b
需要的唯一模块a
是类型信息,编译文件b.js
将不会有require("./a")
语句,也就是说,它不会对a
有运行时依赖性。来自typescript handbook的报价:
编译器检测是否在发出的JavaScript中使用了每个模块。如果模块标识符仅用作类型注释的一部分而从不用作表达式,则不会为该模块发出require调用。
我刚尝试过:
档案a.ts
import { B } from "./b"
export class A {
constructor(public name: string) {}
}
let b = new B();
b.print(new A("This is a random name"));
文件b.ts
import { A } from './a';
export class B {
print(a: A) {
console.log(a.name);
}
}
一起编译它们
tsc a.ts b.ts
这是b.js的结果:
"use strict";
var B = (function () {
function B() {
}
B.prototype.print = function (a) {
console.log(a.name);
};
return B;
}());
exports.B = B;
看到?没有require("./a")
,不像a.js
包含
var b_1 = require("./b");
最有可能的是,你在问题中发布的示例代码是不完整的,真正的b
模块对a
有运行时依赖性 - 找出它的位置并摆脱它,你就不会遇到这个问题。
现在可以在TypeScript 2.9中直接使用。
type MyType = import('mymodule').MyType;
const myValue: import('mymodule').MyType;
你在这里使用了[typescript]标签,所以我假设你正在使用打字稿。
把它变成单行道。取消循环依赖。我可能会将其移动到1个文件中,但您仍然可以像这样拆分它。
a.ts(只是一个界面)
export interface A {
name: string;
new (name: string);
}
b.ts(实施)
import { A } from 'a';
export class B implements A {
/*...*/
}