globalThis is the future.
First, TypeScript files have two kinds of scopes
global scope
If your file hasn't any import or export line, this file would be executed in global scope that all declaration in it are visible outside this file.
So we would create global variables like this:
// xx.d.ts
declare var age: number
// or
// xx.ts
// with or without declare keyword
var age: number
// other.ts
globalThis.age = 18 // no error
All magic come from
var. Replacevarwithletorconstwon't work.
module scope
If your file has any import or export line, this file would be executed within its own scope that we need to extend global by declaration-merging.
// xx[.d].ts
declare global {
var age: number;
}
// other.ts
globalThis.age = 18 // no error
Answer from edvard chen on Stack OverflowYou can see more about module in official docs
globalThis is the future.
First, TypeScript files have two kinds of scopes
global scope
If your file hasn't any import or export line, this file would be executed in global scope that all declaration in it are visible outside this file.
So we would create global variables like this:
// xx.d.ts
declare var age: number
// or
// xx.ts
// with or without declare keyword
var age: number
// other.ts
globalThis.age = 18 // no error
All magic come from
var. Replacevarwithletorconstwon't work.
module scope
If your file has any import or export line, this file would be executed within its own scope that we need to extend global by declaration-merging.
// xx[.d].ts
declare global {
var age: number;
}
// other.ts
globalThis.age = 18 // no error
You can see more about module in official docs
Inside a .d.ts definition file
type MyGlobalFunctionType = (name: string) => void
If you work in the browser, you add members to the browser's window context:
interface Window {
myGlobalFunction: MyGlobalFunctionType
}
Same idea for NodeJS:
declare module NodeJS {
interface Global {
myGlobalFunction: MyGlobalFunctionType
}
}
Now you declare the root variable (that will actually live on window or global)
declare const myGlobalFunction: MyGlobalFunctionType;
Then in a regular .ts file, but imported as side-effect, you actually implement it:
global/* or window */.myGlobalFunction = function (name: string) {
console.log("Hey !", name);
};
And finally use it elsewhere in the codebase, with either:
global/* or window */.myGlobalFunction("Kevin");
myGlobalFunction("Kevin");
Typescript global variables - Stack Overflow
How to define a global variable in a typescript module, which could be used in other modules directly without import?
How to create a truly global variable in TypeScript without window? - LambdaTest Community
Global Variables
Hello folks,
first of all my apologies for my language barriers.
As a main JAVA programmer I've started to split my classes in different TS files like in JAVA. But as I get several messages of 'Cannot find name X' Ive becoming doubtful of my modus operandi.
Also Im getting similar troubles declaring global variables in the different files... again the 'Cannot find name X'.
It seems more complex that it should be... :/
How is it supposed to be built?
-
Global variables: You can't define globals in JAVA, so why try it in Typescript? Do what you would do in Java: Declare a static variable on a class.
-
One class per file: That's perfectly fine and I do it all the time. You have to explicitly import files though. I usually have 1 class per file, and an
index.tsthat exports all these things. EG:
// core/user/IUserService.ts
import { IUser } from "./IUser"
export interface IUserService {
getUserById(id: string): Promise<IUser>
}
// core/user/IUser.ts
export interface IUser {
id: string;
}
// core/user/index.ts
export * from "./IUserService"
export * from "./IUser"
// core/index.ts
export * from "./user"
// http/HttpUserService.ts
import { IUserService, IUser } from "../core/user";
export class HttpUserService implements IUserService {
constructor(
private endpoint: string,
private fetch: Fetch,
) {
}
async public getUserById(id: string): Promise<IUser|null> {
const response = await this.fetch(this.endpoint + "/users/" + id);
return response.status === 200 ? parseUserResponse(await response.json()) : null;
}
}
// essentially a prive function
// no need to embed it in the class since it won't be using `this` either
function parseUserResponse(data: any): IUser {
return ...;
}
// http/index.ts
export * from "./HttpUserService";
// index.ts
export * from "core";
export * from "http";
Also, an example of a "global" variable by using a singleton pattern: https://github.com/tobyhinloopen/injector/blob/master/src/core/Injector.ts
export class Injector {
public static readonly instance = new Injector();
...
}
In Java everything defined in the same package shares the same scope; so you can reference a class in another file without explicitly importing it. Typescript is different: every file has its own scope; so you must explicitly export and import classes and variables between files.
A file in a Typescript project is called a "module" because it gets its own scope. Javascript works the same way when working with CommonJS or ES modules.
CommonJS is the Node module system - Typescript is typically configured to use this system. A bundler (either tsc, Webpack, or Parcel) combines CommonJS modules into one file for use in a browser.
ES modules are the new ECMAScript standard module system. Browsers are upgrading to be able to consume ES modules natively, which may make bundling unnecessary in some cases. But it will take some time for the community to adjust to this new module system. The old module-less system where all browser scripts share one global namespace has been on the way out for some time.
You need to define those properties as static, then you can access it easily like this,
export class Game {
static canvas: JQuery;
static CANVAS_WIDTH: number;
static CANVAS_HEIGHT: number;
bullet: Bullet;
constructor(canvasElem: JQuery) {
Game.canvas = canvasElem;
Game.CANVAS_WIDTH = Game.canvas.width();
Game.CANVAS_HEIGHT = Game.canvas.height();
}
}
export class Bullet {
x: number = 22;
y: number = 22;
public inBounds() {
// accessing static properties
return this.x >= 0 && this.x <= Game.CANVAS_WIDTH && this.y >= 0 && this.y <= Game.CANVAS_HEIGHT;
}
}
This compiles to:
define(["require", "exports"], function(require, exports) {
var Game = (function () {
function Game(canvasElem) {
Game.canvas = canvasElem;
Game.CANVAS_WIDTH = Game.canvas.width();
Game.CANVAS_HEIGHT = Game.canvas.height();
}
return Game;
})();
exports.Game = Game;
var Bullet = (function () {
function Bullet() {
this.x = 22;
this.y = 22;
}
Bullet.prototype.inBounds = function () {
// accessing static properties
return this.x >= 0 && this.x <= Game.CANVAS_WIDTH && this.y >= 0 && this.y <= Game.CANVAS_HEIGHT;
};
return Bullet;
})();
exports.Bullet = Bullet;
});
//# sourceMappingURL=dhdh.js.map
This is a contrived example, but rather than trying to push to global scope, you can use the module scope to enclose a variable that will be used from several classes.
module MyModule {
var x: number = 5;
export class FirstClass {
doSomething() {
x = 10;
}
}
export class SecondClass {
showSomething() {
alert(x.toString());
}
}
}
var a = new MyModule.FirstClass();
a.doSomething();
var b = new MyModule.SecondClass();
b.showSomething();
All the usual rules about multiple things using the same variable apply here - you don't want to enforce a particular order of events on the calling code.
Compiles to:
var MyModule;
(function (MyModule) {
var x = 5;
var FirstClass = (function () {
function FirstClass() {
}
FirstClass.prototype.doSomething = function () {
x = 10;
};
return FirstClass;
})();
MyModule.FirstClass = FirstClass;
var SecondClass = (function () {
function SecondClass() {
}
SecondClass.prototype.showSomething = function () {
alert(x.toString());
};
return SecondClass;
})();
MyModule.SecondClass = SecondClass;
})(MyModule || (MyModule = {}));
var a = new MyModule.FirstClass();
a.doSomething();
var b = new MyModule.SecondClass();
b.showSomething();
Hey guys.
Lately, I've been messing around with TypeScript. I come from a full JS background and I wanted to upgrade myself to TS in my spare time.
For context, I've created numerous APIs using Express with JS and I wanted to see if I can recreate those APIs but this time in TS.
However, I've run into a problem: how do you create global variables in TypeScript?
In a NodeJS environment I would normally just go:
// index.js
global.foo = "and I call it a day"
// controller.js
global.foo = "Modified by a different file."
How do I replicate this behavior in TypeScript?
I'm not asking if I should be using Global Variables, or should I reinvent my existing architecture to not use Global Variables; I just need to know how to do it. I've tried endlessly Googling this and while I've come close to finding a solution none of them seem to fit the bill.
For example: http://marcinbiernat.pl/2020/03/nodejs-globals/
This guy just has him declaring things and it works perfectly. The problem I have with it is: I don't want the declarations to clog up index.ts for example. How do I separate my declarations from my code? Is that even possible?