如何在 TypeScript 中声明全局变量

在 TypeScript 中声明全局变量

How to declare Global Variables in TypeScript

要在 TypeScript 中声明一个全局变量,请创建一个.d.ts文件并使用
declare global{}来扩展全局对象,为必要的属性或方法添加类型。TypeScript.d.ts在查找常规文件的相同位置查找.ts文件。

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

源代码/类型/index.d.ts
/* eslint-disable no-var */

declare global {
  var country: string;
  function multiply(a: number, b: number): number;
}

export {};

上面的示例显示了如何使用名为country字符串和multiplyd 函数的属性扩展全局对象。

请注意,这在您的用例中会有所不同,因此请务必调整属性名称和类型。

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

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

例如,如果您不知道特定属性的类型并希望关闭类型检查,请将其设置为any.

源代码/类型/index.d.ts
/* eslint-disable no-var */

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

export {};

现在,如果在浏览器中使用global,我可以在对象上设置和访问指定属性,Node.js或者在对象上设置和访问指定属性。window

索引.ts
global.country = 'Germany';

console.log(global.country); // 👉️ "Germany"

// ✅ Can also be accessed directly
console.log(country); // 👉️ "Germany"

// 👇️ if you are in browser
// console.log(window.country);

global.multiply = function (a: number, b: number) {
  return a * b;
};

console.log(global.multiply(16, 30)); // 👉️ 450

// ✅ Can also be accessed directly
console.log(multiply(13, 10)); // 👉️ 130

// 👇️ if you are in browser
// console.log(window.multiply(15, 15));

请注意,如果您使用的是 ts-node,您的终端可能仍会出现错误

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

要解决此问题,请在您的命令中
使用该
--files标志,因此您应该运行.ts-nodets-node ./src/index.tsts-node --files ./src/index.ts

我正在使用nodemonts-node这里是我的
nodemon.json文件的内容。

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

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

请注意,这使得multiply函数和country属性可以直接(全局)访问,也可以在global(Node.js) 或window
(Browser) 对象上访问。

索引.ts
global.country = 'Germany';

console.log(country); // 👉️ "Germany"


global.multiply = function (a: number, b: number) {
  return a * b;
};


console.log(multiply(13, 10)); // 👉️ 130

如果你试图访问一个你没有明确添加到你的declare global {}对象中的属性,你会得到一个错误:

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

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

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

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

请注意,您必须根据您的用例更改所提供文件的内容。 index.d.ts

TypeScript.d.ts在查找常规文件的相同位置查找.ts文件,这由文件中的includeexclude设置
决定
tsconfig.json

如果你不能让它工作,你可以尝试使用类型断言

索引.ts
// 👇️ or (global as any) if you are in Node.js
(window as any).example = 'hello world';

console.log((window as any).example);

这种方法应该只在没有其他方法有效时使用,因为每次需要访问windowglobal对象属性时都必须键入any是很烦人的

在声明全局变量时,您还可以使用更直接的方法。

这是一个不使用declare global语法的示例,而是声明

源代码/类型/index.d.ts
/* eslint-disable no-var */

/**
 * IMPORTANT: 👇️
 * file should not have imports or exports
 */
declare var country: string;

declare function multiply(a: number, b: number): number;

该文件直接声明了一个countrymultiply全局变量。

请注意,该.d.ts文件不应包含任何导入或导出,否则您将不得不使用declare global{}前面代码片段中的语法。

现在您可以在代码中设置和访问全局变量。

索引.ts
global.country = 'Germany';

console.log(country); // 👉️ "Germany"

// 👇️ if you are in browser
// console.log(window.country);

global.multiply = function (a: number, b: number) {
  return a * b;
};

console.log(multiply(13, 10)); // 👉️ 130

在 TypeScript 中扩展 Window 接口

If you need to extend the Window interface, use the declare global{} syntax
in a .d.ts file.

src/types/index.d.ts
export {};

declare global {
  interface Window {
    myProperty: any;
  }
}

The example above shows how to extend the Window interface with a property
named myProperty that has a type of any.

Now, I’m able to set and access the specified property on the window object
without getting any errors.

index.ts
window.myProperty = 'hello world';

console.log(window.myProperty);

If you try to access a property that you haven’t added to the extended Window
interface and does not exist on the original Window interface, you’d get an
error:

index.ts
// ⛔️ Property 'example' does not exist on
// type 'Window & typeof globalThis'.ts(2339)
window.example = 'hello';

TypeScript will merge the declared from you Window interface with the original
Window interface, so when you use the window object, you will be able to
access properties from both interfaces.