在 TypeScript 中扩展 Node.js Global (globalThis) 对象

要在 TypeScript 中扩展 Global (globalThis) 对象,需要创建一个 .d.ts 文件并使用 declare global{} 来扩展具有必要属性或方法的类型的全局对象。 TypeScript 在查找常规 .ts 文件的相同位置查找 .d.ts 文件。

在 src 目录中,创建一个包含以下 index.d.ts 文件的 types 目录:

index.d.ts

/* eslint-disable no-var */

interface Employee {
  name: string;
  age: number;
}

declare global {
  var myObj: Employee;
  function sum(a: number, b: number): number;
}

export {};

上面的示例显示了如何使用名为 myObj 的属性扩展全局 (globalThis) 对象,该属性是 Employee 类型的对象和 sum 函数。

注意 ,这在我们的用例中会有所不同,因此请确保调整属性名称和类型。

确保使用 var 关键字为我们打算在其他文件中设置和使用的属性添加类型。

我们需要在 global 对象上添加要访问的所有属性的名称和类型。

例如,如果我们不知道特定属性的类型并想关闭类型检查,请将其设置为 any

/* eslint-disable no-var */

declare global {
  var myObj: any; // 👈️ disables type checking for property
  function sum(a: number, b: number): number;
}

export {};

现在,我们可以在 global 对象上设置和访问指定的属性,而不会出现任何错误。

global.myObj = {
  name: 'James',
  age: 30,
};

console.log(global.myObj.name); // 👉️ "James"
console.log(global.myObj.age); // 👉️ 30

global.sum = (a: number, b: number) => {
  return a + b;
};

console.log(global.sum(50, 50)); // 👉️ 100

注意 ,如果我们使用的是 ts-node,在我们的终端可能仍会出现错误。

问题在于 ts-node 无法识别本地声明文件。

要解决这个问题,请在 ts-node 命令中使用 –files 标志,因此我们应该运行下面的命令

$ ts-node --files ./src/index.ts 

我们将 nodemon 与 ts-node 一起使用,这是我的 nodemon.json 文件的内容。

{
  "watch": ["src"],
  "ext": ".ts,.js",
  "ignore": [],
  "exec": "ts-node --files ./src/index.ts"
}

添加 --files 标志后(仅在使用 ts-node 时才需要),重新启动您的服务器,您应该一切顺利。

注意,这使得 sum 函数和 myObj 属性可以直接(全局)和在全局对象上访问。

global.myObj = {
  name: 'James',
  age: 30,
};

global.sum = (a: number, b: number) => {
  return a + b;
};

console.log(global.myObj); // 👉️ {name: 'James', age: 30}
console.log(global.sum(50, 50)); // 👉️ 100

console.log(myObj); // 👉️ {name: 'James', age: 30}
console.log(sum(50, 50)); // 👉️ 100

如果我们尝试访问未在 declare global{} 对象中显式添加的属性,则会收到错误消息:

// ⛔️ Error: Element implicitly has an 'any'
// type because type 'typeof globalThis'
// has no index signature.ts(7017)
global.hello = 'world';

如果你的 IDE 中仍然出现错误,请尝试将类型目录的路径添加到 tsconfig.json 文件中。

{
  "compilerOptions": {
    // ... rest
    "typeRoots": ["./node_modules/@types", "./src/types"]
  }
}

我们在 index.d.ts 文件中使用 export {} 行将其标记为外部模块。 模块是包含至少 1 个导入或导出语句的文件。 我们必须这样做才能扩大 global 范围。

注意 ,我们必须根据自己的用例更改提供的 index.d.ts 文件的内容。

我们应该在 global 对象上添加我们打算访问的所有属性的名称(和类型)。

/* eslint-disable no-var */

declare global {
  var myObj: any; // 👈️ 禁用属性的类型检查
  function sum(a: number, b: number): number;
}

export {};

提供的文件只是添加了 myObj 类型为 any 的属性,这很可能不是我们需要的。

TypeScript 在查找常规 .ts 文件的相同位置查找 .d.ts 文件,这取决于 tsconfig.json 文件中的包含和排除设置。

TypeScript 会将我们在全局对象上声明的类型与原始类型合并,因此我们将能够从两个声明中访问属性和方法。

免责声明:
1.本站所有内容由本站原创、网络转载、消息撰写、网友投稿等几部分组成。
2.本站原创文字内容若未经特别声明,则遵循协议CC3.0共享协议,转载请务必注明原文链接。
3.本站部分来源于网络转载的文章信息是出于传递更多信息之目的,不意味着赞同其观点。
4.本站所有源码与软件均为原作者提供,仅供学习和研究使用。
5.如您对本网站的相关版权有任何异议,或者认为侵犯了您的合法权益,请及时通知我们处理。
火焰兔 » 在 TypeScript 中扩展 Node.js Global (globalThis) 对象