参考资料
- Extending TypeScript Global object in node.js https://stackoverflow.com/questions/35074713/extending-typescript-global-object-in-node-js
 - 。。。
 
问题描述

当我们想要往全局对象身上注入一些成员时,ts 会报错。本文档解决的就是如何解决类似这样的报错问题。
使用 any 绕过 ts 的检查

一种非常简单粗暴的法子,就是通过 any 类型避开 ts 的类型检查,但是这种做法无法对成员 a 进行类型约束。
比如,现在我们希望给 window 对象身上注入一个成员 a,要求 a 是一个字符串类型,使用 any 就没法做到,需要使用 declare 声明语法来扩展全局对象。
一些必要的背景知识
declare global必须在模块上下文中使用- ts 是如何区分一个文件中的内容处于全局上下文还是模块上下文的?
- 如果一个文件中没有使用 
import或export语句,那么文件中的内容将被视为全局范围。 - 如果一个文件中使用了至少一个 
import或export语句,那么该文件中的所有内容都将被视为模块范围。 
 - 如果一个文件中没有使用 
 - 浏览器环境的全局对象 
window,在 ts 中,对应的接口为Window - nodejs 环境的全局对象 
global,在 ts 中,对应的接口为NodeJS.Global- 在 node 16 中,
NodeJS.Global该接口已经被启用了。 
 - 在 node 16 中,
 
扩展浏览器环境下的 window
// ./1.d.tsexport {}declare global {interface Window {a: string}}
// ./1.tswindow.a = '1'// (property) Window.a: string
采用下面这种简写也是 ok 的。
// 1.d.tsinterface Window {a: string}
// 1.d.tsexport {}declare global {var a: string}
扩展 node 环境下的 global
首先,需要初始化一下工程:
- 新建一个空目录
 - 完成初始化 
npm init -y - 下载 node 的声明文件 
npm i @types/node - 准备俩文件 
./1.ts./1.d.ts 
// 1.d.tsexport {}declare global {var a: string}
// 1.tsglobal.a = '1'// ts 能够推导出 var a: string

其实上述写法有些不严谨,这么写相当于直接在全局上下文扩展了一个 a,即便你不通过 global.a 的方式来访问,依旧可以获取到 a,并且推导出的类型也是 string。

因此,上述写法其实直接用声明全局变量的 declare 语句来写也行
declare var a: string
被弃用的写法:
export {}declare module NodeJS {interface Global {a: string}}
按照需求来看的话,这种写法显然更 nice,因为它确确实实在扩展全局对象 global,并没有污染全局环境。但是很无奈,这玩意儿已被弃用了,暂时还没找到更 nice 的写法。
