As of node@16 the NodeJS.Global interface has been removed in favor of globalThis.

You can declare new global variable in a module file as:

declare global {
  var NEW_GLOBAL: string;
}

And in a non-module file (no top-level import/export) as:

declare var NEW_GLOBAL: string;

Important note: variable must be declared as var. let and const variables don't show up on globalThis.

Answer from aleksxor on Stack Overflow
🌐
Plain English
plainenglish.io › blog › typescript-and-global-variables-in-node-js-59c4bf40cb31
TypeScript and Global Variables in Node.js
August 14, 2021 - How to make global variables in Node.js using TypeScript and make sure the types are correct.
Discussions

Node.js global variable and TypeScript
Have one file that declares the property on the NodeJS.Global interface with the any type. This file has to be clean of imports or refrences. ... Then in the second file you declare a global variable that has the correct type. ... Note that when using this method all global.foo usages will still, annoyingly, be of any type. However, you will at least be able to use foo as Ifoo type globally. Good enough to move forward, however. I wish the TypeScript ... More on stackoverflow.com
🌐 stackoverflow.com
Configure module files available in Node.js global scope
From @hubletkoresh on November 15, 2017 9:3 I have an MVC application, with multiple local modules, one of which being models that I install to global scope to enable runtime cyclic references. Unf... More on github.com
🌐 github.com
19
November 15, 2017
global variables in nodejs

You probably shouldn't be using a global variable for what you're trying to do, but…

to let TypeScript know about your own properties on the global object you need to augment the Global interface in a d.ts file:

export interface Global {
 myProp: string;
}

If all you want is to 'share' stuff across files (i.e. modules) you probably want to export from your modules rather than add to the global object.

More on reddit.com
🌐 r/typescript
2
3
October 15, 2015
Global Variables
You can just export an object from any module. export const global = { foo: "and I call it a day } import { global } from "./global.ts"; global.foo = "Modified by a different file." Sure you might need to add an import statement everywhere, but then you'll be able to see everywhere it's being used as well More on reddit.com
🌐 r/typescript
3
2
February 12, 2024
🌐
Xwlee
xwlee.github.io › extending-type-script-global-object-in-node-js
Extending TypeScript Global Object in NodeJS | Lee Xiang Wei
12.05.2021 — nodejs, typescript, ... global.myFunctionName = () => { console.log("hi"); }; To extends global object in TypeScript, you need to augment the global namespaces ·...
🌐
Blake Williams
blakewilliams.me › posts › using-ts-node-with-global-types
Using ts-node with Global Types | Blake Williams
September 7, 2020 - We can use declare to tell TypeScript that global contains a property with a given type. declare global let myGlobal: number } Now we’re able to set global.myGlobal in the application without type errors. Getting right into it with a contrived example, given a global.d.ts declaring a global ...
🌐
Marcinbiernat
marcinbiernat.pl › 2020 › 03 › nodejs-globals
NodeJS globals and TypeScript · Marcin Biernat
March 22, 2020 - Setting a global value in NodeJS couldn’t be simpler: Note: Make sure that you have @types/node installed. Let’s start by trying to just assign the value and see what happens: If we look at the type of global it’s globalThis. Fortunately TypeScripts declaration merging allows us to extend this interface to include our new attribute:
Top answer
1 of 4
13

Here's an approach. I don't know if this is the 'correct' way of doing things, but it works for me with TypeScript 3.7.4.

  1. Assuming your source files live in a folder src, create a new folder src/types and create a file global.d.ts in this folder.
  2. Author your declarations using one of the following strategies:
    • If you need to import external types into your declaration file, use the following syntax:
import { Express } from 'express';

declare global {
  namespace NodeJS {
    interface Global {
      __EXPRESS_APP__: Express;
    }
  }
}
  • If your declaration file does not contain any imports, the above will not work, and you'll need to use this syntax instead:
declare namespace NodeJS {
  interface Global {
    __CONNECTION_COUNT__: number;
  }
}
  1. Make sure your global.d.ts file (and any other files you might add to src/types) is picked up by the TypeScript compiler, by adding the following to your tsconfig.json file:
{
  "paths": {
    "*": ["node_modules/*", "src/types/*"]
  }
}
  1. Use the global variable as normal inside your code.
// Below, `app` will have the correct typings
const app = global.__EXPRESS_APP__;
2 of 4
7

I found this works.

Have one file that declares the property on the NodeJS.Global interface with the any type. This file has to be clean of imports or refrences.

node.d.ts

declare namespace NodeJS{
    interface Global {
        foo: any
    }
}

Then in the second file you declare a global variable that has the correct type.

global.d.ts

import IFoo from '../foo'

declare global {

  const foo:Ifoo

}
🌐
GitHub
github.com › microsoft › TypeScript › issues › 20046
Configure module files available in Node.js global scope · Issue #20046 · microsoft/TypeScript
November 15, 2017 - const ModelA = require('./ModelA').model; const ModelB = require('./ModelB').model; global['ModelA'] = ModelA; global['ModelB'] = ModelB; module.exports = { ModelA, ModelB };
Author   mjbvz
Find elsewhere
🌐
JavaScript in Plain English
javascript.plainenglish.io › typescript-and-global-variables-in-node-js-59c4bf40cb31
TypeScript and Global Variables in Node.js | by Tomas Nilsson | JavaScript in Plain English
August 16, 2021 - import "express";declare global { namespace Express { interface Request { token: string, UserID: string } } }export { }; More content at plainenglish.io · JavaScript · Programming · Typescript · Nodejs · Software Development · Follow · 174K followers ·
🌐
Plain English
plainenglish.io › blog › how-to-create-global-variables-in-typescript-with-node-js-9ca24f648991
How to Create Global Variables in TypeScript with Node.js
December 13, 2021 - Here we are declaring a global variable, interface and type, with this, all of them will be available everywhere in our project. And yes, unfortunately, we have to use var, otherwise, it won’t work. So far, so good, now if we want TypeScript to recognize our global variable, interface and type, we have to create a @types folder and put there our .d.ts file.
🌐
TypeScript
typescriptlang.org › download
TypeScript: How to set up TypeScript
You can use npm to install TypeScript globally, this means that you can use the tsc command anywhere in your terminal.
🌐
Reddit
reddit.com › r/typescript › global variables
r/typescript on Reddit: Global Variables
February 12, 2024 -

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?

🌐
GitHub
github.com › DefinitelyTyped › DefinitelyTyped › issues › 4249
node.d.ts: interface Global / NodeJS.Global breaks current Node+TypeScript · Issue #4249 · DefinitelyTyped/DefinitelyTyped
May 1, 2015 - Those are all ES6 types. The current Node.js / v8 version implements them, but they aren't native types, as far as the TypeScript compiler is concerned.
Author   chbrown
🌐
ReactHustle
reacthustle.com › blog › how-to-extend-global-object-declaration-in-typescript
How to Extend Global Object Declaration in Typescript | ReactHustle
The Typescript compiler will look for .d.ts files and include them in other type definitions that you may have installed. ... The next step is to use declaration merging to add more definitions to whatever interface you need. In this case, it's the ProcessEnv interface. declare global { namespace NodeJS { interface ProcessEnv { // Define custom environment variables SECRET: string | null; MY_ENVIRONMENT_VARIABLE: "value1" | "value2" | "value3" | null; } } } export {}
🌐
GitHub
github.com › vagnercardosoweb › nodejs-structure-with-typescript › blob › main › global.d.ts
nodejs-structure-with-typescript/global.d.ts at main · vagnercardosoweb/nodejs-structure-with-typescript
Structure already configured to start any API in NODE with Typescript - nodejs-structure-with-typescript/global.d.ts at main · vagnercardosoweb/nodejs-structure-with-typescript
Author   vagnercardosoweb
🌐
Node.js
nodejs.org › api › typescript.html
Modules: TypeScript | Node.js v25.8.2 Documentation
By default Node.js will execute TypeScript files that contains only erasable TypeScript syntax. Node.js will replace TypeScript syntax with whitespace, and no type checking is performed. To enable the transformation of non erasable TypeScript syntax, which requires JavaScript code generation, ...
Top answer
1 of 2
2

The piece of code you shared is making use of global augmentation https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation

// Hint typescript that your global object will have a custom signin function
declare global {
  function signin(): Promise<string[]>;
}

// Assign value to global.signin
global.signin = async () => { /* implementation */ };

Likely one or multiple modules ("mongoose", "supertest", "../app") imported by the test file is using global.signin (or window.signin) at some point (or maybe one of their nested imports is => look for "signin(" in the project). Thus for testing purposes, global.signin needed to be mocked. However just adding global.signin = something would raise a typescript error, because signin is not a standard global variable. This is where declare global comes into play. It hints typescript that in your particular context, a signin function is expected to exist in global scope.

2 of 2
1

JavaScript/TypeScript running in node will try to resolve anything it can't find in the current local scope in global (the same way a browser would look in window). Any function or variable you can access globally (e.g. setTimeout()), can also be accessed with global. as prefix. It just makes it explicit.

What happens in your code are two things:

declare global {
  function signin(): Promise<string[]>;
}

Here it tells typescript's type system that the global object also has a function called signin. This part is not required but it makes sense required for typescript to allow you to access / define that function, in JavaScript you simply define it.
https://www.typescriptlang.org/docs/handbook/declaration-merging.html has some details how declare works.

global.signin = async () => {
   // code ...
};

And here it is actually added to the global object.

In JavaScript non strict mode you could even write (notice the lack of var/let/const/global.)

signin = async () => {
   // code ...
};

I don't see signin getting used anywhere in that code so the reason for it is unclear to me. As long as the file that defines it gets loaded you can call the function simply by referring to it as signin(). The global. is added implicitly.

The purpose of

declare global {
  namespace Express {
    interface Request {
      currentUser?: UserPayload;
    }
  }
}

is more practical, in express you may want to add properties to your requests that get added by middleware. By declaring that the Express Request has a property called currentUser you get to do

app.get((req, res) => {
   const user: UserPayload = req.currentUser
   ...
})

without typescript complaining about an unknown property. More on that for example https://blog.logrocket.com/extend-express-request-object-typescript/

Top answer
1 of 4
10

to bundle global types, do the following. form typescript

  • specify default typings directory at typeRoots. .e.g "typeRoots": ["./src/types"].
  • create a file /src/types/global.d.ts in the specified directory
  • declare your types in the file inside declare global {} and make sure to have export {} if you don't already export anything.
2 of 4
7

The short answer is:

TypeScript does not support Global types without importing the file referring to the type.

More details:

One example that I found doing this was Next.js - when creating a TypeScript app using npx create-next-app@latest --typescript you can start importing *.css files (for example) and get the correct type.

Where I got confused is that I originally thought that the type was coming from the next-env.d.ts but even when I deleted the file, *.css import was still working in Visual Studio code. But the reason it was, is because a file in the pages directory were importing Next.js' index.d.ts file.

Basically, in Visual Studio Code, as soon as your import a type somewhere in your project, if it's global, it will be accessible everywhere.

Workaround

So what can be done with the current TypeScript capabilities? To support new file types, you will need a file loader such as Webpack. The logical thing to do would be to add a reference to the file type declaration in the file loader itself. This way, as soon as you configure your file loader to be able to import the file, you will inherit the type:

  1. create a txt.d.ts in our package's source directory (e.g. src) - you can use any name for the file, it's not important
  2. if you are using eslint, add an entry to ignore the type file (e.g. 'src/*.d.ts' in your ignorePatterns option
  3. Since you are adding a d.ts file in your source that is not managed by tsc, you need to add a script that will perform the following actions:
    1. Copy txt.d.ts in the target directory of the compiled files for your package
    2. Add this line at the top of your package's file loader (e.g. loader/index.d.ts: /// <reference types="../txt" />\r\n - this will link the declaration file back into your package. Note that you can add this reference to any file of your package.

This workaround will only work once you import the file referencing back to the declaration - this is the only way TypeScript can be made aware that this type exists (see https://github.com/microsoft/TypeScript/issues/49124).

Another alternative could also be to add manual steps (in a readme file) to add a global type declaration file.

🌐
Stack Overflow
stackoverflow.com › questions › 69192564 › declare-global-variable-in-nodejs
typescript - Declare global variable in NodeJS - Stack Overflow
declare global { let LOG: Logger; } // eslint-disable-next-line @typescript-eslint/no-namespace declare namespace globalThis { let LOG: Logger; } globalThis.LOG = new Logger();