在打字稿中使用 globalThis

Nic*_*key 6 typescript

我正在尝试在 Typescript 中使用 globalThis,我想就如何以更好的方式编写它提出一些建议。
目前的实现是这样的:

创建一个文件types/global.d.ts并在里面添加

interface Global {
   foo: string
}

declare let foo: Global["foo"];
Run Code Online (Sandbox Code Playgroud)

tsconfig.json添加

"files": [
  "types/global.d.ts"
]
Run Code Online (Sandbox Code Playgroud)

然后,以设定的值foo使用

(globalThis as any).foo = "The value of foo"
Run Code Online (Sandbox Code Playgroud)

我不喜欢这种方法首先是需要样板(但我认为这是无法避免的),其次是(globalThis as any).foo =表达式

Chr*_*ert 73

2021 年 10 月更新

适用于 TypeScript 4.3+

错误

元素隐式具有any类型,因为类型typeof globalThis没有索引签名。TS(7017)

解决方案

declare global {
  function myFunction(): boolean;
  var myVariable: number;
}

globalThis.myFunction = () => true;
globalThis.myVariable = 42;
Run Code Online (Sandbox Code Playgroud)
  • 重要提示:此解决方案只能通过var使用(不要使用letor const)声明变量来起作用。

背景

请参阅有关TypeScript 问题 30139的讨论。

传统上,在 Node.js 上下文中指定 TypeScript 声明块的方法如下:

// Does not work as of October 2021 (TypeScript 4.3+)
declare global {
  module NodeJS {
    interface Global {
      myFunction(): boolean;
      myVariable: number;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

tsconfig.json:noImplicitAny

noImplicitAny请注意,如果 TypeScript 设置设置为 ,则会抑制此错误false。建议启用noImplicitAny更好的类型检查。

  • 哇!那个 `var` 而不是 `let`/`const` 是一个救星! (15认同)

And*_*ert 19

我的回答基于爱德华·卡萨诺瓦的回答。我正要编辑它,但适合我的代码仍然有很多差异,而且我现在可以提供一些关于此的附加信息。

这是基于TypeScript 4.3.5

// typings/globals.d.ts (depending on your tsconfig.json)

export {}

interface Person {
  name: string
}

declare global {
  var someString: string
  var globalPerson: Person
}
Run Code Online (Sandbox Code Playgroud)

export如果没有至少一个(或import)关键字,这将不起作用。这会将这个文件转换为 ES 模块,这是其正常工作所必需的。您可以导出任何语句或添加空的export {}.

上面的代码添加了以下句柄的类型:

someString
window.someString
globalThis.someString

globalPerson.name
window.globalPerson.name
globalThis.globalPerson.name
Run Code Online (Sandbox Code Playgroud)

另一方面,以下情况也是可能的,但结果不同:

export {}

declare global {
  let someLetString: string
  const someConstString: string
}
Run Code Online (Sandbox Code Playgroud)

这只会添加以下句柄的类型:

someLetString
someConstString
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,您不能为 分配任何值someConstString。这对于一些较旧的 JS 库可能很有用,这些库将功能添加到全局范围而不是导出它。在这种情况下,库仍然可以为其赋值,const因为它只是一种类型,而不是真正的const。这const只有 TypeScript 代码知道。但请注意,let不要const将属性添加到全局对象windowglobalThis。所以,var这里可能是更好的选择。


Cha*_*and 11

结合其他答案,这就是最终对我有用的内容。

在 TS 文件的顶部(或在全局类型文件中):

declare module globalThis {
    let myObj: { foo: string };
}
Run Code Online (Sandbox Code Playgroud)
globalThis.myObj = { foo: 'bar' };
Run Code Online (Sandbox Code Playgroud)

  • 声明名称与内置全局标识符“globalThis”冲突 (4认同)

c_o*_*goo 5

您可以在打字稿中使用声明合并来实现此目的。

在你的global.d.ts文件中:

export declare global {
  interface Window {
    // add you custom properties and methods
    foo: string
  }
}

Run Code Online (Sandbox Code Playgroud)

现在您可以使用Window.foo而无需打字稿警告您。

我在dev.to上写了一篇关于此的迷你博客