如何在模块声明中重新导出命名空间定义

时间:2017-01-22 09:00:00

标签: typescript types lodash typescript-typings

首先,我想了解为什么一些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. 如何简单地将单向方法转换为另一种方法?

1 个答案:

答案 0 :(得分:0)

花了很多时间为此寻找解决方案后,我终于开始工作了!

/** 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命名空间的一部分被消费者访问。 此外,您可以在B定义的命名空间范围内正确访问index.d.ts

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

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