我一直在阅读DefinitelyTyped上的一些声明文件,并经常遇到这样的文件:
declare function domready(callback: () => any) : void;
export = domready;
export as namespace domready;
我理解前两行 - 声明一个函数并将该函数导出为模块对象。但最后一行是什么?我的声明文件中是否需要这个?它做了什么?
答案 0 :(得分:4)
如果您还不熟悉,UMD是一种创建模式,允许将相同的JavaScript库用作全局变量(可以在任何地方访问)或作为< em> module (在运行时专门加载的模块),具体取决于环境。
许多库都使用UMD模式编写。例如,您可以写
moment.parse("12-31-2017")
在浏览器中,但在node.js中编写如下代码:
const m = require("moment");
m.parse("12-31-2017")
当您编写export
export function parse
声明时,TypeScript知道您在第二个代码块中描述模块。但是,如果您正在编写.d.ts文件的库也创建了一个全局变量,则可以使用UMD模块声明语法描述该全局变量:
export as namespace the_global_identifier;
某些UMD库始终创建全局,而其他必须必须导入,如果它们是在存在模块系统的环境中加载的话。一般情况下,库并没有清楚地记录他们使用的行为,这意味着声明文件作者并不真正知道会发生什么,这意味着TypeScript是保守的,只有 允许访问全局标识符引用它的文件是不是模块。
如果您正在编写声明文件并且不确定它们的库是否为UMD,请检查看起来像这样的模式:
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.mymodule = global.mymodule || {})));
}(this, function (exports) { 'use strict';
function myFunction() {
console.log('hello world');
}
}));
这是UMD的气味:很多typeof
检查&#34;导出&#34;,&#34;模块&#34;和&#34;定义&#34;然后分配到&#34;出口&#34;赋予大函数体的参数。如果你没有在库代码中看到这个,那几乎肯定不是UMD模块,你应该不写一个export as namespace
声明。