添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I have a node.js app that attaches some config information to the global object:

global.myConfig = {
    a: 1,

The TypeScript compiler doesn't like this because the Global type has no object named myConfig:

TS2339: Property 'myConfig' does not exist on type 'Global'.

I don't want to do this:

global['myConfig'] = { ... }

How do I either extend the Global type to contain myConfig or just tell TypeScript to shut up and trust me? I'd prefer the first one.

I don't want to change the declarations inside node.d.ts. I saw this SO post and tried this:

declare module NodeJS  {
    interface Global {
        myConfig: any

as a way to extend the existing Global interface, but it doesn't seem to have any effect.

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.

Not working for me, the compiler still complains with the following message: 'Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature'. – Anthony Luzquiños Oct 19, 2021 at 0:01 and how to use this NEW_GLOBAL which is declared and set in Server.ts in eg. UserController? Do I need to somehow import it? How Typescript knows that it was already declared in Servert.s? – Suisse Nov 16, 2021 at 12:57

Your file needs to be clean of any root level import or exports. That would turn the file into a module and disconnect it from the global type declaration namespace.

More : https://basarat.gitbooks.io/typescript/content/docs/project/modules.html

I can't quite figure this out. I don't have a vendor.d.ts, so I made one, but it seems to have no effect. Should I be importing it? – Justin Oct 31, 2016 at 1:25 @basarat - RE: "Your file needs to be clean of any root level import or exports" would it not be possible to apply the "global modifying module" here as per typescriptlang.org/docs/handbook/declaration-files/templates/… ? If I understand that example correctly, adding something along the lines of declare global { namespace NodeJS { ... }} should allow you to have both the global namespace augmentation and your module exports. – Jan Molak Dec 25, 2016 at 22:46 How do I use interfaces from external modules as types? I want spotConfig of 'Sequelize.Sequelize' type. Now how do I do that? – Sid Verma Jun 20, 2017 at 3:14 This won't help for implicit global references, e.g. spotConfig instead of global.spotConfig. To fix this, add declare const spotConfig: any;. – Oliver Joseph Ash Nov 8, 2018 at 10:25

I suggest to define custom types. I do it under src/types/custom.d.ts file in my project:

declare global {
  namespace NodeJS {
    interface Global {
        myConfig: {
          a: number;
          b: number;

Then I ensure these are considered by Typescript in tsconfig.json file:

"files": [ "src/types/custom.d.ts"

Now you're safe to use your custom property:

console.log(global.myConfig.a);
                This is the better answer. Just as extending Window client-side should use declare global.
– Robert Penner
                Sep 29, 2017 at 19:17

We're using "@types/node": "^7.0.18" and TypeScript Version 2.3.4. Our tsconfig.json file looks like this:

"compilerOptions": { "module": "commonjs", "target": "es6" "exclude": [ "node_modules" I am getting the error: TS2339: Property 'myConfig' does not exist on type 'Global'. with it. – Benny Code Feb 29, 2020 at 11:14

Use 'namespace' instead of 'module' to declare custom TypeScript

If you use any of the above answers and are using a newer version of Typescript you'll get a nag about using "module". You should consider namespace instead.

In order to satisfy the requirement here you'll actually need more than extending the Global interface. You'll also need to create a constant with the type as well if you want it to be accessible directly from the "globalThis" context.

NOTE: while the OP asked about an object literal the process is the same as you see here below. Rather than the "Debug" type being a function you would simply define the interface as need, then change "debug:" to myConfig or whatever you wish.

// typically I'll store the below in something like "typings.d.ts"
// this is because, at least typically, these overrides tend to
// be minimal in nature. You could break them up and Typescript
// will pick them up if you wish.
// Augmentations for the global scope can only be directly nested 
// in external modules or ambient module declarations.
export {}
declare global {
  // Definition or type for the function.
  type Debug = (label: string) => (message: any, ...args: any[]) => void
  // If defining an object you might do something like this
  // interface IConfig { a: number, b: number }
  // Extend the Global interface for the NodeJS namespace.
  namespace NodeJS {
    interface Global {
      // Reference our above type, 
      // this allows global.debug to be used anywhere in our code.
      debug: Debug
  // This allows us to simply call debug('some_label')('some debug message')
  // from anywhere in our code.
  const debug: Debug

How the above might be used

For completeness in this example all we did was define a global so we can log a simple debug message. Here's how we'd bind the method to our global context.

global.debug = (label: string) => (message: any, ...args: any[]) => console.log(message, ...args)

We can also call our global debug method directly:

debug('express')(`${req.method}: ${req.url}`)
import Global = NodeJS.Global;
export interface CDTGlobal extends Global {
  cdtProjectRoot: string

and then using it in other files like so

import {CDTGlobal} from "../lib/my.d.ts";
declare const global: CDTGlobal;
const cwd = global.cdtProjectRoot; // works
                I am attempting something similar, but in regards to reading a configuration JSON file and then having it globally accessible by all my modules. I'm attempting to figure out a solution where I do not have to "re-read" the json file in each module but can't seem to pull it off.
– Chason Arthur
                Mar 7, 2019 at 18:21

Only downside is when using it you will have to turn off the ESLint rule @typescript-eslint/no-namespace.

For completeness here is my tsconfig.json:

"compilerOptions": { "declaration": true, "emitDecoratorMetadata": true, "esModuleInterop": true, "experimentalDecorators": true, "forceConsistentCasingInFileNames": true, "jsx": "react", "lib": ["dom", "es2017"], "module": "commonjs", "moduleResolution": "node", "noEmitOnError": true, "noImplicitReturns": true, "noUnusedLocals": true, "noUnusedParameters": true, "outDir": "dist", "removeComments": true, "resolveJsonModule": true, "rootDir": "src", "sourceMap": true, "strict": true, "target": "es6" "exclude": ["dist", "node_modules"] This did work for me, to define a global emit function from a Ava test written in TypeScript. – Adrien Joly Jun 1, 2020 at 9:04

I can get both type check and code intelligence.

declare namespace NodeJS {
  interface Global {
    property: string

But interface Global is point to global.GLOBAL.

You can get correct type check, is because:

declare var global: NodeJS.Global & typeof globalThis;

But you can not get better code intelligence by useing global.property, unless use global.GLOBAL.property.

So, you need to define global var global and extend interface Global both:

// myglobal.d.ts
declare namespace NodeJS {
  interface Global {
    property: string
declare var global: NodeJS.Global & typeof globalThis

And now you can get property intelligence when you type global.

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.