【问题标题】:How to re-export namespace definition inside module declaration如何在模块声明中重新导出命名空间定义
【发布时间】:2017-06-06 22:39:57
【问题描述】:

首先,我想了解为什么某些 TypeScript 定义文件以两种形式给出(我将尝试用lodash 示例来展示这一点)。

第一个是“基于命名空间”(来自@types/lodash 定义):

export = _;
export as namespace _;
declare var _: _.LoDashStatic;
declare namespace {
    (...)
}

第二个是“基于模块”(来自typings 模块定义):

declare module 'lodash' {
    var _: _.LoDashStatic;
    namespace _ {
        (...)
    }
    export = _;
}

同一库的两个定义源显示不同的方法。这里的权衡是什么?为什么来自@types/... 源的一些类型在第一个中给出,而在第二个中给出另一个?

我在将“基于命名空间”的定义与位于我的项目范围之外的共享代码一起使用时遇到了一些问题,因此我更喜欢“基于模块”的定义。 好了,第二步来了。我想标准化这些定义并且只使用@types/... 源但是当我得到“基于命名空间”的定义(如lodash)时,我想编写一些自定义定义(尽可能短)来重新导出该命名空间以“基于模块”的方式。

我尝试过这样的事情:

declare module "lodash" {
    import * as x from "lodash";

    var _: x.LoDashStatic;
    namespace _ {}
    export = _;
}

这当然是行不通的(除了没有cannot find module... 错误之外),但我认为这很能说明我在这里想要完成的事情。 我的目标是使用@types/lodash/index.d.ts 中声明的命名空间,并使用模块声明将其导出到不同的文件(如custom_typings/lodash.d.ts)中。

总结出两个问题:

  1. 为什么定义以两种不同的方式构建?
  2. 如何简单地将一种方法转换为另一种方法?

【问题讨论】:

    标签: typescript types lodash typescript-typings


    【解决方案1】:

    经过这么多时间寻找解决方案,我终于成功了!

    /** index.d.ts */
    import './models';
    
    // tslint:disable-next-line:no-namespace
    declare namespace MyLib {
        export interface A {
            // ...
        }
    
        // ...
    }
    
    
    /** extra.d.ts */
    // tslint:disable-next-line:no-module
    declare module './index' {
        export interface B {
            // ...
        }
    
        // ...
    }
    

    AB 都可以作为 MyLib 命名空间的一部分被消费者访问。 此外,您可以在index.d.ts 中定义的命名空间范围内正确访问B

    我同意语法不是很好,但它可以解决问题。 lodash 类型中使用了类似的方法:

    虽然在上面的 POC 中我更喜欢使用 es6 import 语法,但 lodash 类型使用 /// <reference。这两个选项都有效,因此由您决定。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-23
      • 2020-11-15
      • 1970-01-01
      • 2015-01-07
      • 2015-06-03
      • 1970-01-01
      • 2015-05-10
      相关资源
      最近更新 更多