【问题标题】:Why the ES2015 module syntax is preferred over custom TypeScript namespaces?为什么 ES2015 模块语法优于自定义 TypeScript 命名空间?
【发布时间】:2021-01-10 13:43:52
【问题描述】:

来自typescript-eslint docs

自定义 TypeScript 模块 (module foo {}) 和命名空间 (namespace foo {}) 被认为是组织 TypeScript 代码的过时方式。现在首选 ES2015 模块语法 (import/export)。

来自打字稿docs

模块可以同时包含代码和声明。

模块还依赖于模块加载器(例如 CommonJs/Require.js)或支持 ES 模块的运行时。模块为捆绑提供了更好的代码重用、更强的隔离和更好的工具支持。

同样值得注意的是,对于 Node.js 应用程序,模块是默认的,我们建议在现代代码中使用模块而不是命名空间。

我对这个问题的目标是找出为什么模块语法比命名空间更受欢迎。

这是我到目前为止所做的:

PROJECT_TYPES.d.ts

我有多个 d.ts 文件,我在其中声明了包含我在项目源文件中使用的类型的命名空间。

declare namespace MY_NAMESPACE {
  type FOO = "FOO"
}

这样做,我可以在项目的任何源文件中执行以下操作:

someFile.ts

const foo: MY_NAMESPACE.FOO =  "FOO";

而且它不需要任何import/export

注意事项:

  • 我正在使用d.ts 文件,因为这些文件不包含任何import / export 代码。
  • 我使用的是declare namespace 而不仅仅是namespace,因为没有declare 关键字我会收到@typescript-eslint/no-unused-vars 警告。

考虑到MY_NAMESPACE 是一个唯一的名称,这应该被认为是一种不好的做法吗?在这种情况下,我是否有理由使用 modules 而不是 namespaces ?我不应该使用d.ts 文件吗?

我的意思是,Typescript 文档提到:

模块为捆绑提供了更好的代码重用、更强的隔离和更好的工具支持。

但是我不认为遵循我上面描述的模式会失去任何这些好处,因为我所有的“真实”实际编译结果代码都在模块中分离。但是为什么我的类型应该只在模块中呢?

【问题讨论】:

    标签: typescript module namespaces typescript-typings .d.ts


    【解决方案1】:

    TLDR

    namespace 的目的是提供构造的逻辑分组,但是 ES2015 模块的引入允许我们使用文件系统来实现这一点,而不会污染全局范围。它还为我们在使用类型时提供了更大的灵活性。

    示例

    ES2015 之前

    // src/geometry/types.d.ts
    declare namespace Geometry{
        export type Shape = 'circle' | 'square'
    }
    
    // src/geometry/main.ts
    let myShape: Geometry.Shape = 'square'
    

    发布 ES2015

    // src/geometry/types.ts
    export type Shape = 'circle' | 'square'
    
    // src/geometry/main.ts
    import { Shape } from './types'
    let myShape: Shape = 'square'
    
    //src/geometry/index.ts
    export * as Geometry from './types'
    

    参考

    【讨论】:

      猜你喜欢
      • 2020-02-04
      • 2022-10-04
      • 1970-01-01
      • 2020-03-30
      • 2016-02-25
      • 2014-06-20
      • 2019-04-30
      • 1970-01-01
      • 2012-09-26
      相关资源
      最近更新 更多