在 TypeScript 中声明全局变量
How to declare Global Variables in TypeScript
要在 TypeScript 中声明一个全局变量,请创建一个.d.ts
文件并使用
declare global{}
来扩展全局对象,为必要的属性或方法添加类型。TypeScript.d.ts
在查找常规文件的相同位置查找.ts
文件。
在您的src
目录中,创建一个types
包含以下
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
.
/* 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
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-node
ts-node ./src/index.ts
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
),重新启动服务器,您应该一切顺利。
请注意,这使得multiply
函数和country
属性可以直接(全局)访问,也可以在global
(Node.js) 或window
(Browser) 对象上访问。
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 {}
对象中的属性,你会得到一个错误:
// ⛔️ Error: Element implicitly has an 'any'
// type because type 'typeof globalThis'
// has no index signature.ts(7017)
global.hello = 'world';
如果您的 IDE 仍然出现错误,请尝试将您的types
目录路径添加到您的tsconfig.json
文件中。
{
"compilerOptions": {
// ... rest
"typeRoots": ["./node_modules/@types", "./src/types"]
}
}
我们使用文件中的export {}
行将index.d.ts
其标记为外部模块。模块是至少包含 1 个import
orexport
语句的文件。我们必须这样做才能扩大global
范围。
index.d.ts
TypeScript.d.ts
在查找常规文件的相同位置查找.ts
文件,这由文件中的include
和exclude
设置
决定tsconfig.json
。
如果你不能让它工作,你可以尝试使用类型断言
// 👇️ or (global as any) if you are in Node.js
(window as any).example = 'hello world';
console.log((window as any).example);
这种方法应该只在没有其他方法有效时使用,因为每次需要访问window
或global
对象属性时都必须键入any是很烦人的
在声明全局变量时,您还可以使用更直接的方法。
这是一个不使用declare global
语法的示例,而是声明
/* eslint-disable no-var */
/**
* IMPORTANT: 👇️
* file should not have imports or exports
*/
declare var country: string;
declare function multiply(a: number, b: number): number;
该文件直接声明了一个country
和multiply
全局变量。
请注意,该.d.ts
文件不应包含任何导入或导出,否则您将不得不使用declare global{}
前面代码片段中的语法。
现在您可以在代码中设置和访问全局变量。
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.
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.
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:
// ⛔️ 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.