[英]Export assignment and exporting types in TypeScript ambient module
我正在尝试为我们的应用程序特定的config
模块添加类型。 config
模块是从JSON文件动态生成的,所以输入很棘手。 由于它是一个节点模块,我使用环境模块进行打字。
// config.d.ts
declare module 'config' {
interface AppConfig {
name: string;
app_specific_thing: string;
}
const config: AppConfig;
export = config;
}
我如何导出AppConfig
所以我可以使用它作为这样的类型:
import * as config from 'config';
const appConfig: config.AppConfig;
如果我直接在config
模块中导出AppConfig,则会出错:
TS2309:导出分配不能在具有其他导出元素的模块中使用。
如果我将AppConfig
移动到另一个文件(例如./app_config
)来保存导出并将它们导入config.d.ts
则会出错:
TS2439:环境模块声明中的导入或导出声明不能通过相关模块名称引用模块。
如果我将AppConfig
导出放在同一个文件中,但在config
模块之外,则会出错:
TS2665:扩充中的模块名称无效。 模块'config'解析为$ PROJ / config / lib / config.js中的无类型模块,无法扩充。
这类似于Typescript错误“导出分配不能在具有其他导出元素的模块中使用”。 同时扩展typescript定义 ,要求我希望能够直接在其他TS文件中将AppConfig
作为类型导入。
答案需要一个令人困惑的Typescript概念:
声明合并 - 编译器将使用相同名称声明的两个单独声明合并到一个定义中。 在这种情况下,我们创建两个config
声明。
// config.d.ts
declare module 'config' {
// This nested namespace 'config' will merge with the enclosing
// declared namespace 'config'.
// https://www.typescriptlang.org/docs/handbook/declaration-merging.html
namespace config {
interface AppConfig {
name: string;
app_specific_thing: string;
my_enum: FakeEnum;
}
interface MyInterface {}
// See side note below
type FakeEnum = 'A' | 'B' | 'C';
}
const config: AppConfig;
export = config;
}
您可以像这样使用导入:
import * as config from 'config';
import { FakeEnum, MyInterface } from 'config';
作为旁注,您不能将enums
与环境模块 ( declare module 'config'
)一起使用,因为枚举编译为JS对象而您无法将新对象添加到您无法控制的模块。 你可以通过伪造一个带有union类型的枚举来解决这个问题:
type FakeEnum = 'A' | 'B' | 'C';
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.