打字稿导出类型和模块值

时间:2020-04-06 17:48:42

标签: typescript es6-modules

我想导出一个与值同名的类型。这是一个示例模块:

// foo.ts

export type Foo = string;

export function create(): Foo {
  // ...
}

此模式起作用的原因是什么

// index.ts
import * as _Foo from "./foo";
export const Foo = _Foo;
export type Foo = _Foo.Foo;

但是这些模式不是吗?

// No compiler error but value is not exported
export type Foo = import("./foo").Foo;
export * as Foo from "./foo";

// Duplicate identifier error
import type { Foo } from "./foo";
import * as Foo from "./foo";
export { Foo };

// Individual declarations in merged declaration 'Point' must be all exported or all local. [2395]
import * as Foo from "./foo";
export { Foo };
export type Foo = Foo.Foo;

1 个答案:

答案 0 :(得分:1)

键入别名do not produce a value

让我解释一下您的示例中发生了什么

// Types (Foo) and values (create) are imported into a single variable
import * as _Foo from "./foo"; 

// The module is reexported with another name
export const Foo = _Foo;

// The type is reexported with another name
export type Foo = _Foo.Foo;

编译版本不包含课程类型

var _Foo = require("./foo");
exports.Foo = _Foo;

此后,如果将Foo用作类型,则将其正确解析为string,但是如果将Foo用作值,则它是带有create的对象字段。

有趣的是,您现在可以使用typeof Foo,它将是{ create: () => string }

前进 以下内容与前面的内容非常相似,但是由于第一个导入明确声明了它是一种类型,因此可以为导出值使用相同的名称

export type Foo = import("./foo").Foo; // does not produce a variable
export * as Foo from "./foo"; // named value export

编译为

exports.Foo = require("./foo");

下一个是有点棘手的,老实说,我不知道为什么它不起作用。我猜这可能是一个错误,因为import type是一项闪亮的新功能,但我没有找到它。

import type { Foo } from "./foo";
import * as Foo from "./foo";
export { Foo };

本地定义的类型有效:

type Foo = string;
import * as Foo from "./foo";
export { Foo };

最后一个,因为在此导入中声明了Foo,因此无法与其合并。您可以查看this issue了解详情。

import * as Foo from "./foo";
export { Foo }; 
export type Foo = Foo.Foo; // <- local definition

可以使用临时标识符重写它,就像在第一个示例中所做的那样:(它不起作用,请参见下面的更新)

import * as _Foo from './Foo'
export { _Foo as Foo }
export type Foo = _Foo.Foo

更新

最后列出的代码段可产生正确的js输出,但在将导出用作值时会抛出错误:

import * as _Foo from './merged'
const x: Foo = '1234'; // Ok
const y = Foo.create(); // <- TS2693: 'Foo' only refers to a type, but is being used as a value here.

这似乎是个错误,但我找不到它发布了