仅从模块导入类型信息

时间:2016-12-05 20:39:50

标签: typescript

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

4 个答案:

答案 0 :(得分:11)

您无需执行任何特殊操作即可仅导入模块a中的类型信息。

Typescript将为您完成 - 如果模块b需要表单a的唯一内容是类型信息,则编译文件b.js将不会有require("./a")语句,即,它不会对a具有运行时依赖性。引自typescript handbook

  

编译器检测是否在发出的模块中使用了每个模块   JavaScript的。如果模块标识符仅用作类型的一部分   注释,永远不作为表达,然后不需要调用   为该模块发射。

我刚尝试过:

文件 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上具有运行时依赖性 - 找出它的位置并摆脱它,并且您赢了'有这个问题。

答案 1 :(得分:10)

现在可以在TypeScript 2.9中直接实现。

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

答案 2 :(得分:5)

从TypeScript 3.8开始,使用//get mac address $mac=file_get_contents("/sys/class/net/wlan0/address"); echo "mac=".$mac;

import type

参考:

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#type-only-imports-exports

答案 3 :(得分:-1)

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

让它成为一条单行道。取消循环依赖。我可能会把它移到1个文件中,但你仍然可以像这样拆分它。

a.ts (只是一个界面)

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

b.ts (实施)

import { A } from 'a';

export class B implements A {
    /*...*/
}