在 TypeScript 中使用外部模块声明一个全局变量

Declare a global variable using an external module in TypeScript

本文关键字:全局变量 一个 声明 模块 TypeScript 外部      更新时间:2023-09-26

我正在用TypeScript https://www.npmjs.com/package/html2commonmark 创作一个npm模块。该模块可以在nodejs(通过使用require(和浏览器(通过在浏览器中加载node_modules/html2commonmark/dist/client/bundle.js(中使用。

我最近添加了 *.d.ts 文件,以便在使用 "moduleResolution": "node" 时获取输入信息。这很好用,安装我的模块时,它可以在打字稿中使用。因此:以下一段打字稿代码编译没有错误:

// After installing using npm install html2commonmark
// using "moduleResolution": "node"
import * as html2commonmark from 'html2commonmark';
let converter = new html2commonmark.JSDomConverter();

美丽!

现在我想在浏览器中运行我的模块。如前所述,我需要添加一个脚本标记以node_modules/html2commonmark/dist/client/bundle.js我的索引.html页面。之后,html2commonmark全局变量应该可用。问题是:如何让打字稿编译知道全局变量的存在?以下一段 TS 代码无法编译:

let converter = new html2commonmark.BrowserConverter(); 
// error TS2304: Cannot find name 'html2commonmark'.

即使我添加了一个 global.d.ts 文件,我似乎也无法导入我的外部模块并声明我的全局变量:

// Something like this does not work :(
import * as b from 'html2commonmark';
declare var html2commonmark: typeof b;

我明白这是为什么。通过使用导入关键字,我的ts文件被转换为外部模块,因此需要导入。然而,我觉得我的场景很常见。即:一个 npm 模块,其中包含一个 npm 组件和浏览器的捆绑包,该捆绑包将功能公开为全局变量。

有没有办法使用外部模块中的定义声明全局变量?当我刚刚用 TS 编写整个源代码时,我不想将我的 api 重写为(绝对类型化样式(命名空间......

编写在

浏览器和 Node.js 中工作的外部模块的正确方法是:

    使用
  1. --module umd 标志,然后在浏览器中使用 AMD 加载程序加载模块
  2. 使用
  3. --module commonjs 标志,然后使用 webpack 或 browserify 等捆绑器

换句话说,当您开始编写模块化代码时,盲目地向 HTML 文件添加<script>标记不再是将该代码加载到浏览器中的正确方法。正如您不应该在 Node.js 中触摸全局范围一样,您也不应该在浏览器中触摸全局范围。你可以用if (typeof window !== 'undefined') (<any>window).global = yourObject;破解它,但说真的,永远不要这样做,这是错误的,它会破裂

至于将外部模块内部的接口公开到全局范围,没有办法做到这一点,因为您必须import外部模块才能获取对其接口的引用,此时您已经创建了另一个外部模块。从 TypeScript 1.8 开始,您可以使用 declare global 从模块内部扩充全局类型。