首先,我想了解为什么一些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
)。
总结出两个问题:
答案 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 {
// ...
}
// ...
}
然后,A
和B
都可以作为MyLib
命名空间的一部分被消费者访问。
此外,您可以在B
定义的命名空间范围内正确访问index.d.ts
。
我同意语法不是很好,但是可以解决问题。 lodash键入中使用了类似的方法:
在我上面的POC中,我更喜欢使用es6 import
语法,但lodash键入使用/// <reference
。这两个选项都有效,因此由您决定。