TypeScript - 将 module/namespaces 附加到 window

TypeScript - Attach module/namespaces to window

我已经使用 ES2015 构建了很多 API 和应用程序,但我还不习惯 TypeScript 中的最佳实践,所以也许你可以帮助我。 假设我正在为一家商店建造一个 API/SDK。目标是用户包含我的 js 文件并通过 window 对象访问商店及其名称空间,就像使用 angular 和其他库一样。

window.shop.init();
window.shop.cart.get();
window.shop.cart.set();
window.shop.cart.clear();

在 ECMAScript 2015 中,我会编写 getset 等方法,将它们导入我的主文件并扩展商店对象,最后扩展全局对象。

// in my cart.js namespace file
export {get} from './get';

// in my shop.js
import * as cart from './cart';

global.shop = {
    cart
}

作为 ES2015 命名空间的好方法,在 TypeScript 中使用所有这些模块和命名空间关键字感觉有点不对。

我基本上想在 TS 中实现相同的功能。我试过类似下面的方法,但没有成功。

module shop {
    export const cart = {...}
}

(<any>window).shop = shop;

namespace shop {
    // ...
}

(<any>window).shop = shop;

有些教程声称模块会自动附加到 global/window 对象,但这对我来说并没有发生。

我正在使用 TypeScript 1.8.10。非常感谢任何帮助!

There where some tutorials claiming that a module is automatically attached to the global/window object, but that did not happen for me.

可能是因为您的 namespace 代码在 (ES6) module 而不是 script 中? differences between scripts and modules are detailed here.

下面的代码在浏览器中创建一个全局变量 shop 如果它作为 脚本 加载,即带有标签 <script src="shop.js">(或者你可以将此文件与其他 JavaScript 文件连接起来,例如 uglifyjs).

// File shop.ts
namespace shop {
    export const cart = { /* ... */ }
}

如果您的代码作为 ES6 模块加载(即借助 Webpack、SystemJS、RequireJS 或其他),您的解决方案有效:

(<any>window).shop = shop;

@paleo 的回答并不完美。 它只是抑制商店的类型推断。

今天早上我也遇到了类似的问题。我在 SO 上尝试了很多 "solutions",但是其中 none 绝对不会产生类型错误,并且可以在 IDE(webstorm 或 vscode)中启用触发类型跳转。

最后,从这里开始

https://github.com/Microsoft/TypeScript/issues/3180#issuecomment-102523512

,我找到了 为全局变量附加类型的合理解决方案,它充当 interface/class 和命名空间两者 .

示例如下:

// typings.d.ts
declare interface Window {
    shop?: MyNamespace & typeof MyNamespace
}

declare interface MyNamespace {
    somemethod?()
}

declare namespace MyNamespace {
    // ...
}

现在,上面的代码将命名空间MyNamespace和接口MyNamespace的类型合并到全局变量shop中(window的属性) .