在TypeScript中创建一个全局变量

Vac*_*ano 64 typescript

在JavaScript中,我可以这样做:

 something = 'testing';
Run Code Online (Sandbox Code Playgroud)

然后在另一个文件中:

 if (something === 'testing')
Run Code Online (Sandbox Code Playgroud)

它将something被定义(只要它们以正确的顺序被调用).

我似乎无法弄清楚如何在TypeScript中做到这一点.

这就是我尝试过的.

在.d.ts文件中:

interface Window { something: string; }
Run Code Online (Sandbox Code Playgroud)

然后在我的main.ts文件中:

 window.something = 'testing';
Run Code Online (Sandbox Code Playgroud)

然后在另一个文件中:

 if (window.something  === 'testing')
Run Code Online (Sandbox Code Playgroud)

这很有效.但我希望能够失去window.它的一部分,让我的something全球化.有没有办法在TypeScript中做到这一点?

(如果有人感兴趣,我真的想为我的应用程序设置日志记录.我希望能够log.Debug从任何文件调用而无需导入和创建对象.)

Ben*_* B. 51

.d.ts定义文件中

type MyGlobalFunctionType = (name: string) => void
Run Code Online (Sandbox Code Playgroud)

如果您在浏览器中工作,则将成员添加到浏览器的窗口上下文中:

interface Window {
  myGlobalFunction: MyGlobalFunctionType
}
Run Code Online (Sandbox Code Playgroud)

NodeJS的想法一致:

declare module NodeJS {
  interface Global {
    myGlobalFunction: MyGlobalFunctionType
  }
}
Run Code Online (Sandbox Code Playgroud)

现在你声明根变量(它实际上将存在于窗口或全局)

declare const myGlobalFunction: MyGlobalFunctionType;
Run Code Online (Sandbox Code Playgroud)

然后在常规.ts文件中,但作为副作用导入,实际上是实现它:

global/* or window */.myGlobalFunction = function (name: string) {
  console.log("Hey !", name);
};
Run Code Online (Sandbox Code Playgroud)

最后在代码库的其他地方使用它,使用以下任一方法:

global/* or window */.myGlobalFunction("Kevin");

myGlobalFunction("Kevin");
Run Code Online (Sandbox Code Playgroud)

  • 这实在是太复杂了。 (8认同)
  • 您将d.ts文件放在哪里,以及如何配置TypeScript来加载它? (7认同)
  • @Benoit我没有得到"但作为副作用导入"的部分.你是什​​么意思?.我尝试过这样做,但它不适合我,你能分享一个源代码示例吗? (6认同)
  • (只是发表评论)谈论很多工作来创建一个简单的全局变量!大声笑 (3认同)
  • 这对于“.ts”文件工作得很好,但是当我在“.tsx”文件中使用“window.myGlobalFunction”时,它就不行了。我还需要改变什么吗?! (2认同)

Vik*_*ary 24

这是我修复它的方式:

脚步:

  1. 声明一个全局命名空间,例如 custom.d.ts 如下:
declare global {
    namespace NodeJS {
        interface Global {
            Config: {}
        }
    }
}
export default global;
Run Code Online (Sandbox Code Playgroud)
  1. 将上面创建的文件映射到“tsconfig.json”中,如下所示:
"typeRoots": ["src/types/custom.d.ts" ]
Run Code Online (Sandbox Code Playgroud)
  1. 在任何文件中获取上面创建的全局变量,如下所示:
"typeRoots": ["src/types/custom.d.ts" ]
Run Code Online (Sandbox Code Playgroud)

笔记:

  1. 打字稿版本:“3.0.1”。

  2. 就我而言,要求是在启动应用程序之前设置全局变量,并且该变量应该在整个依赖对象中访问,以便我们可以获得所需的配置属性。

希望这可以帮助!

谢谢


小智 21

这里发布的文字是文章的简短版本Node.js 中的 TypeScript 和全局变量一文的简短版本

\n

自从 TypeScript 3.4 发布以来,有一种记录在案的方法可以做到这一点。

\n

在项目根目录下创建一个文件,名称为global.d.ts为以下内​​容。请注意:

\n
    \n
  • 使用 var , it\xe2\x80\x99s 需要此功能(请参阅typescriptlang.org有关此信息,
  • \n
  • 如果没有export {},所有变量都将变成any
  • \n
\n
declare global {\n    var Config: {\n        Foo: string;\n    };\n    var Foo: string;\n}\nexport { };\n
Run Code Online (Sandbox Code Playgroud)\n

确保 tsconfig.json 具有正确的include和部分exclude部分。示例如下:

\n
"include": [\n    "src/**/*.ts",\n  ],\n  "exclude": [\n    "node_modules",\n    "<node_internals>/**",\n    "bin/**"\n  ]\n
Run Code Online (Sandbox Code Playgroud)\n

要使用变量,只需执行以下操作:

\n
import * as Logger from \'./logger\';\n\n// Initialize early\nglobal.log = Logger;\n\n// Use it\nlog.Info("Booting system...");\n
Run Code Online (Sandbox Code Playgroud)\n

享受 :)

\n


Vac*_*ano 13

如果我将JavaScript与TypeScript结合使用,我发现了一种有效的方法.

logging.d.ts:

declare var log: log4javascript.Logger;
Run Code Online (Sandbox Code Playgroud)

登录声明.js:

log = null;
Run Code Online (Sandbox Code Playgroud)

initalize-app.ts

import './log-declaration.js';

// Call stuff to actually setup log.  
// Similar to this:
log = functionToSetupLog();
Run Code Online (Sandbox Code Playgroud)

这使它成为全局范围,TypeScript知道它.所以我可以在我的所有文件中使用它.

注意:我认为这只有效,因为我将allowJsTypeScript选项设置为true.

如果有人发布纯TypeScript解决方案,我会接受.


tfo*_*one 7

好吧,所以你做的事情可能更加丑陋,但无论如何......

但我这样做......

在纯TypeScript中你可以做的是使用如下eval函数:

declare var something: string;
eval("something = 'testing';")
Run Code Online (Sandbox Code Playgroud)

以后你就可以做到

if (something === 'testing')
Run Code Online (Sandbox Code Playgroud)

这只不过是在没有TypeScript拒绝编译的情况下强制执行指令的黑客攻击,我们declare var让TypeScript编译其余的代码.

  • 强烈建议不要使用“eval”,这就是为什么我建议使用此解决方案 /sf/answers/3988915311/ (4认同)
  • 这真的应该用`.d.ts` 定义文件来代替。 (3认同)
  • @DragonRock我试过Chrome和FF.所以我真的不确定发生了什么.无论如何最终做声明var myglobalvar; (<any> window).myglobalvar = {}; 然后我可以在没有窗口的情况下引用它. (2认同)
  • 这对我有用:`export declare const SERVER = "10.1.1.26";` (2认同)

小智 6

我只用这个

import {globalVar} from "./globals";
declare let window:any;
window.globalVar = globalVar;
Run Code Online (Sandbox Code Playgroud)

  • 这会丢弃所有类型信息。也可以使用Javascript。 (3认同)

edv*_*hen 6

全球这就是未来。

// Way 1
var abc: number
globalThis.abc = 200 // no error

// Way2
declare var age: number
globalThis.age = 18 // no error
Run Code Online (Sandbox Code Playgroud)

注意:包含以上代码的文件不能包含任何import语句

到目前为止,这些是我想出的扩展全局对象的方法。

所有的魔术都来自var。替换为varlet否则const将不起作用。

我试图globalThis通过声明合并来扩展模块,但是失败了。

  • 为我工作(至少现在)非常感谢,我希望这个答案能够上升。仅供参考:就我而言,我需要在 linter 的 `globalThis` 行上方添加 `// @ts-ignore`。 (2认同)

Ale*_*xey 6

我花了几个小时来找出正确的方法来做到这一点。就我而言,我试图定义全局“日志”变量,因此步骤是:

1)配置您tsconfig.json以包含您定义的类型(src/types文件夹,node_modules - 由您决定):

...other stuff...
"paths": {
  "*": ["node_modules/*", "src/types/*"]
}
Run Code Online (Sandbox Code Playgroud)

2)创建src/types/global.d.ts具有以下内容的文件(没有导入! - 这很重要),随意更改any以满足您的需求+使用window界面而不是NodeJS如果您使用浏览器:

/**
 * IMPORTANT - do not use imports in this file!
 * It will break global definition.
 */
declare namespace NodeJS {
    export interface Global {
        log: any;
    }
}

declare var log: any;
Run Code Online (Sandbox Code Playgroud)

3)现在你终于可以log在需要的地方使用/实现了:

// in one file
global.log = someCoolLogger();
// in another file
log.info('hello world');
// or if its a variable
global.log = 'INFO'
Run Code Online (Sandbox Code Playgroud)


Yux*_*Xie 5

globalThis使用更具体的示例(仅使用 TypeScript,不与 JavaScript 混合)扩展有关(请参阅MDNTypeScript 3.4 note )的其他答案,因为该行为相当混乱。v12.14.1所有示例都在 Nodejs和 TypeScript下运行Version 4.2.3

具有全局范围的最简单的情况

declare var ENVIRONMENT: string;
globalThis.ENVIRONMENT = 'PROD';
console.log(ENVIRONMENT);
console.log(globalThis.ENVIRONMENT);
// output
// PROD
// PROD
Run Code Online (Sandbox Code Playgroud)

该文件没有importexport所以它是一个全局范围的文件。您可以编译上述 TypeScript 代码,不会出现任何错误。请注意,您必须使用var. 使用let会抛出error TS2339: Property 'ENVIRONMENT' does not exist on type 'typeof globalThis'.

您可能会注意到,我们declare对变量进行了处理,而不是以下同样有效的方法。

var ENVIRONMENT: string;
ENVIRONMENT = 'DEV';
globalThis.ENVIRONMENT = 'PROD';
console.log(ENVIRONMENT);
console.log(globalThis.ENVIRONMENT);
// output
// DEV
// PROD
Run Code Online (Sandbox Code Playgroud)

输出来自 Nodejs v12.14.1。我还在 Chrome 中测试了它(编译为 JS 后),并且都输出PROD. 所以我建议globalThis一直使用。

具有模块范围的简单案例

declare var ENVIRONMENT: string;
globalThis.ENVIRONMENT = 'PROD';
export {};
Run Code Online (Sandbox Code Playgroud)

一旦我们添加export语句,它就变成了一个模块作用域文件,它会抛出error TS7017: Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature.The Solution is to Augmented GlobalScope

declare global {
  var ENVIRONMENT: string;
}
globalThis.ENVIRONMENT = 'PROD';
console.log(globalThis.ENVIRONMENT);
export {};
Run Code Online (Sandbox Code Playgroud)

你还是得用,否则var你就会得到error TS2339: Property 'ENVIRONMENT' does not exist on type 'typeof globalThis'.

导入副作用

// ./main.ts
import './environment_prod';

console.log(ENVIRONMENT);
console.log(globalThis.ENVIRONMENT);
Run Code Online (Sandbox Code Playgroud)
// ./environment_prod.ts
declare var ENVIRONMENT: string;
globalThis.ENVIRONMENT = 'PROD';
Run Code Online (Sandbox Code Playgroud)

或者

// ./environment_prod.ts
declare global {
  var ENVIRONMENT: string;
}
globalThis.ENVIRONMENT = 'PROD';
export {}; // Makes the current file a module.
Run Code Online (Sandbox Code Playgroud)

浏览两个文件

假设main.tsenvironment_prod.ts都是入口文件。Browserify会将它们(编译为 JS 后)包装到本地作用域函数中,这需要使用globalThis.

// ./main.ts
declare var ENVIRONMENT: string;
console.log(ENVIRONMENT);
console.log(globalThis.ENVIRONMENT);

// ./environment_prod.ts
declare var ENVIRONMENT: string;
globalThis.ENVIRONMENT = 'PROD';
Run Code Online (Sandbox Code Playgroud)

但共享一个声明文件会更加类型安全,然后两个条目文件都可以导入该声明文件,以避免变量名称或类型名称的拼写错误。

// ./main.ts
import './environment';

console.log(ENVIRONMENT);
console.log(globalThis.ENVIRONMENT);

// ./environment_prod.ts
import './environment';

globalThis.ENVIRONMENT = 'PROD';

// ./environment.ts
type Environment = 'PROD' | 'DEV' | 'LOCAL';

declare var ENVIRONMENT: Environment;
Run Code Online (Sandbox Code Playgroud)

请注意,顺序很重要:browserify environment_prod.js main.js > bin.js


归档时间:

查看次数:

91724 次

最近记录:

6 年 前