You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript声明文件中变量与命名空间声明的差异及选型建议

TypeScript模块默认导出声明的两种方式差异与推荐方案

你提到的两种声明方式,核心差异和适用场景如下:

两种方式的差异

方式一:声明变量

declare var myModule: {
    foo(): void;
    bar(): void;
};

export default myModule;
  • 本质是声明一个具体的变量实例,类型是匿名的对象类型。
  • 无法直接复用这个类型,如果其他地方需要引用该模块的类型,必须通过typeof myModule来间接获取。
  • 语义上更偏向“描述一个已存在的变量”,而非“定义模块导出的结构”。

方式二:声明命名空间

declare namespace MyModule {
    function foo(): void;
    function bar(): void;
}

export default MyModule;
  • 命名空间原本是为全局环境下避免命名冲突设计的,在模块内部使用属于误用场景。
  • 这里导出的是命名空间作为“值”,但实际模块导出的是一个普通对象,语义不匹配,容易造成类型理解混淆。
  • 虽然可以直接用MyModule作为类型,但命名空间的设计初衷并非用来描述模块导出对象的结构。

更优的推荐方案

更符合TypeScript模块声明规范的是先定义接口,再导出默认值,兼顾语义清晰和类型复用性:

declare module 'my-module' {
  // 定义可复用的接口
  interface MyModule {
    foo(): void;
    bar(): void;
  }

  // 声明默认导出的对象符合该接口
  const myModule: MyModule;
  export default myModule;
}

如果不需要复用类型,也可以简化为直接声明默认导出的结构:

declare module 'my-module' {
  export default {
    foo(): void;
    bar(): void;
  };
}

这种方案的优势:

  • 语义精准,直接对应模块默认导出的对象结构。
  • 接口可单独导出供其他地方复用,扩展性更强。
  • 完全符合TypeScript模块声明的设计逻辑,避免变量或命名空间的误用。

内容的提问来源于stack exchange,提问作者user2248702

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 23:53:14