node.js - 在库中提供可扩展的 Typescript 接口
我正在使用 TypeScript 构建一个应该支持第三方插件的库。库的构造函数应该接受核心库和所有插件的选项,因为模块将在构造函数中加载它们。
是否可以提供一个基础的 Options 接口,每个插件都可以扩展它以添加自己的属性和类型,从而在整个顶层应用程序(使用该库和插件)中,Options 接口既反映核心选项,也反映插件的选项?
所以像这样的依赖结构:
- user-app
|- my-library
|- my-library-plugin-a
|- my-library-plugin-b
其中 my-library 定义了以下内容:
export interface Options {
coreOption : string;
}
并且 my-library-plugin-a 如下扩展它:
export interface PluginAOptions extends Options {
pluginA : boolean;
}
并且 my-library-plugin-b 如下扩展它:
export interface PluginBOptions extends Options {
pluginB : Record<string, string>;
}
对于 user-app 的开发者,该应用在其依赖项中包含所有三个模块,从 my-library 导出的 Options 接口应如下所示:
interface Options {
coreOption : string;
pluginA : boolean;
pluginB : Record<string, string>;
}
所以这就是他们的自动完成应该显示的内容,以及 TypeScript 编译器应该检查的内容。
使用 Typescript 这样的东西有可能吗?
答案#1
你不能指望从 my-library 获得所有扩展选项。
这不是关于 TypeScript 的问题,而是关于依赖关系的工作原理。my-library 对插件一无所知,而且它本该如此。如果它以某种方式可以导出插件添加的选项,那么它将依赖于那些插件,从而使插件架构变得毫无意义。
在 user-app 中,你只需使用 plugin-a 和 plugin-b 的选项并将它们组合起来。
const theOption: PluginAOptions & PluginBOptions = { ... }
user-app 是知道并决定使用 plugin-a 和 plugin-b 的人。这就是为什么它应该并且可以使用这些插件中的类型。
答案#2
这可以使用 TypeScript 的声明合并功能实现:
我的库:
export interface Options {
coreOption : string;
}
my-library-plugin-a:
import {Options} from 'my-library';
export module 'my-library' {
export interface Options {
pluginA: boolean;
}
}
my-library-plugin-b:
import {Options} from 'my-library';
export module 'my-library' {
export interface Options {
pluginB: Record<string, string>;
}
}
