Joe*_*Joe 1 typescript typescript-typings
我正在尝试为config特定于我们的应用程序的模块添加类型。该config模块是从 JSON 文件动态生成的,因此很难输入。因为它是一个节点模块,所以我使用环境模块进行打字。
// config.d.ts
declare module 'config' {
interface AppConfig {
name: string;
app_specific_thing: string;
}
const config: AppConfig;
export = config;
}
Run Code Online (Sandbox Code Playgroud)
我如何还导出AppConfig以便我可以将它用作这样的类型:
import * as config from 'config';
const appConfig: config.AppConfig;
Run Code Online (Sandbox Code Playgroud)
如果我直接在config模块中导出 AppConfig,它会出错:
TS2309:不能在具有其他导出元素的模块中使用导出分配。
如果我移动AppConfig到另一个文件(例如./app_config)来保存导出并将它们导入到config.d.ts它的错误中:
TS2439:环境模块声明中的导入或导出声明不能通过相对模块名称引用模块。
如果我将AppConfig导出放在同一个文件中,但在config模块之外,则会出现以下错误:
TS2665:扩充中的模块名称无效。模块 'config' 解析为 $PROJ/config/lib/config.js 中的无类型模块,无法扩充。
这类似于Typescript 错误“不能在具有其他导出元素的模块中使用导出分配”。同时根据我希望能够AppConfig直接在其他 TS 文件中作为类型导入的要求扩展打字稿定义。
答案需要一个令人困惑的 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;
}
Run Code Online (Sandbox Code Playgroud)
您可以像这样使用导入:
import * as config from 'config';
import { FakeEnum, MyInterface } from 'config';
Run Code Online (Sandbox Code Playgroud)
附带说明一下,您不能enums与环境模块(the declare module 'config')一起使用,因为枚举会编译为 JS 对象,并且您无法向不受控制的模块添加新对象。您可以通过伪造具有联合类型的枚举来解决此问题:
type FakeEnum = 'A' | 'B' | 'C';
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3003 次 |
| 最近记录: |