使用打字稿创建库/包时向使用者公开类型的最佳方法?

时间:2018-12-03 19:45:04

标签: typescript module

一段时间以来,我一直在搜索和阅读相关信息,但是仍然无法解决这个问题。

当我使用打字稿创建库或包时,我喜欢将declaration设置为true,以便ts编译器编译源代码时,它将自动为我生成声明文件。典型的库或程序包通常具有一个入口文件和一堆相互依赖的文件。因此,构建结果的输出将如下所示:

.
├── build
|   ├── entry.js (or entry.min.js in production)
|   ├── entry.d.ts (it depends on moduleA)
|   ├── moduleA.d.ts (it depends on moduleB)
|   ├── moduleB.d.ts
|   ├── types.d.ts (contains shared types for every body)
|   └── util.d.ts (declarations for some random util functions)

package.json中,我将设置为:

{
  ...
  "main": "./build/entry.js",
  "types": "./build/entry.d.ts",
  ...
}

问题是,即使entry.js具有我要向消费者公开的所有API,entry.d.ts也没有我也要公开的所有类型。这是因为即使entry.ts中有importtypes.ts,类型声明也不会自动从中导入。消费者可能想使用我保存在types.ts(因此types.d.ts)中的一些枚举,而不是entry.ts(因此entry.d.ts)中的枚举。

使用这些类型的一种方法是将其重新导出到条目文件中,例如:

export * from './types';
// or
export { EnumA } from './types';

这将允许消费者这样做:

import * as types from 'mylib';
// or 
import { EnumA } from 'mylib';

这是我现在正在做的事情,它更多是一个手动工作流程,很可能我忘记导出消费者实际上需要使用我的库的某些类型。我可以将所有类型/接口/枚举放在一个types.ts文件中,然后导出所有内容,但是我不确定这是否正确。

typescript团队正在使用名称空间来处理此问题(例如server typesservice types),但是IMO是多余的,因为我们已经在使用ES6模块。有关更多信息,请参见great cup example for explaining namespaces with modules

另一种解决方法是让消费者这样做

import * as types from 'mylib/build/types'

但是IMO这也是一种不好的做法,因为我们实际上向用户公开了实现细节,我们将来可能会更改它。

我还要补充一点,如果我想为具有commonjs或AMD结构的ES5代码生成库,则typescript offical document表示要使用export =。显然,这将阻止您再使用export * from './types',因此上述解决方法将不再起作用。

这就是我现在的位置。有什么建议么?现在,我倾向于像打字稿团队一样使用名称空间,但我想听听更多的想法。

0 个答案:

没有答案