仅从模块导入类型信息

问题描述 投票:5回答:3

假设我有两个文件,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中的类型得到静态类型检查。这可能吗?

typescript
3个回答
11
投票

您无需执行任何特殊操作即可从模块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有运行时依赖性 - 找出它的位置并摆脱它,你就不会遇到这个问题。


10
投票

现在可以在TypeScript 2.9中直接使用。

type MyType = import('mymodule').MyType;
const myValue: import('mymodule').MyType;

-1
投票

你在这里使用了[typescript]标签,所以我假设你正在使用打字稿。

把它变成单行道。取消循环依赖。我可能会将其移动到1个文件中,但您仍然可以像这样拆分它。

a.ts(只是一个界面)

export interface A {
    name: string;
    new (name: string);
}

b.ts(实施)

import { A } from 'a';

export class B implements A {
    /*...*/
}
© www.soinside.com 2019 - 2024. All rights reserved.