繁体   English   中英

在TypeScript环境模块中导出分配和导出类型

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM