type 'typeof globalThis' has no index signature
Asked Answered
P

15

71

i get this error whenever i try to add a function to the global nodejs global namsepace in a TypeScript environment.

Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature

declaring the global namespace

declare global {
  namespace NodeJS {
    interface Global {
      signin(): string[]
    }
  }
}

so if i try this

global.signin = () => {}

it returns a

Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature

Pennate answered 22/7, 2021 at 8:36 Comment(5)
I was hoping for a proper answer to this exact question. Started getting this error while trying to upgrade to NextJS v11 with Webpack v5, only solution I have found was to install @types/[email protected] as a dependency. Still looking for a better solution, but I found this info here if it helps. github.com/facebook/jest/issues/11640Snipe
declare global only works if it is included in the project, and there are a couple of ways to do that. Could you please tell me, in which file do you put declare global? Also, is it in the same file as global.signin = () => {} ?Sulphonamide
Oh no it’s not in the same file. Had it in another file in my project that was meant for jest setup. It doesn’t have to be in the same file to work because you’re targeting a global namespace which is meant to be available all through your codebase in the same parent folder.Pennate
Maybe try using (global as any).signin = () => {}Counterproof
For anyone trying to use it with a library: let cached = (global as any).mongooseStemson
P
1

in my own case i didn't quite realize until later that the global namespace i declared was case sensitive.

instead of this. before my question was edited it was namespace NODEJS

declare global {
  namespace NODEJS {
    interface Global {
      signin(): string[]
    }
  }
}

it was supposed to be this

declare global {
  namespace NodeJS {
    interface Global {
      signin(): string[]
    }
  }
}

pay attention to NODEJS and NodeJS. After i made these changes, typescript was cool with it and it work the way i expected it to.

Pennate answered 19/9, 2021 at 8:33 Comment(2)
This doesn't work with the latest versions of @types/node.Pomp
And sorry I guess I hijacked your question :pPomp
R
84

I was having a similar issue and I found that node's global typings were changed recently-ish; you can now override them by doing:

// global.d.ts
declare global {
    function someFunction(): string;
    var someVariable: string;
}

Note: this will not work with let or const you must use var.

// index.ts
global.someFunction = () => "some value";
global.someVariable = "some value";
Rondo answered 18/9, 2021 at 1:39 Comment(12)
I tried but TS says Statements are not allowed in ambient contexts..Pomp
@Pomp I edited my answer to make it more clear about what goes in each fileRondo
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'.Alikee
I needed to add export {} to global.d.ts to workaround "Augmentations for the global scope can only be directly nested in external modules or ambient module declarations." 👍. @AnthonyLuzquiños - I wonder if the compiler is aware of your global.d.ts file? I include it in tsconfig.json {..., "include": ["src/**/*", "global.d.ts"]}, hthEncasement
I worked, partially. VSCode error is now gone, but I'm still getting the same error when I try to run it. I have created a project, in case you want to give it a try. I'm using node 16.13.0, yarn 1.22.17 and my so is: 5.10.79-1-MANJARO.Alikee
@AnthonyLuzquiños. I have the same issue. The VS Code error is gone, but I get ` error TS7017: Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature.`Mangosteen
Hi @Shamoon, I finally solve the issue, it was related to ts-node, this is a related question to that, I have also wrote a Medium article about it, here is it.Alikee
Just like to add that I kept tripping up here as i had an the "no-var" ESLint rule however when using declare you must use var and not let or const as I found out.Goatsbeard
@JossBird I edited the answer to clear up any confusion for anyone else that stumbles across this.Rondo
what's the reason that it works with var, but not with let or const?Jussive
This works in node 16Chamomile
Getting TS2669: Augmentations for the global scope can only be directly nested in external modules or ambient module declarations. in node18Torrez
T
51

Below is an example for Node v16

// globals.d.ts
declare module globalThis {
    var signin: () => string[];
}
Tidbit answered 1/2, 2022 at 5:31 Comment(7)
This seems to be the only answer anywhere on the internet that is up to date. Not sure how you knew this answer. My only caveat is it was auto-corrected by my editor to declare namespace globalThisTrawl
I second @Trawl this is the only one that works in node v16Jori
where is this globals.d.ts supposed to be? do we need create it or is it already thereVlaminck
@CircuitPlanet you need create the file with name "globals.d.ts", the typescrit join the config because it is global, so you can create it in any folder of your applicationTidbit
If you have explicitly provided one or more files in TypeScript's config with the include property (like "include": [ "src/app.ts" ]), make sure to also include the *.d.ts file, where you declared your globals (globals.d.ts in this example)Hassi
Is there a way to make it extend an existing interface? Or in other words, make the globalThis have the properties of my interface MyWindow { ... }?Pompea
@Pompea you can use the composition. ``` interface MyWindow { ... } declare module globalThis { var window: MyWindow; } ``` It's impossible to make "globalThis" have its properties by interface or type, because "globalThis" is a namespace, in this case.Tidbit
A
24

I had the same problem with a svelte.kit app. my database module use a global variable to store the dbClient as a promise. VSCode stop complain when the global.d.ts file had this content.

import type { MongoClient } from 'mongodb'

declare global {
  namespace globalThis {
    var _mongoClientPromise: Promise<MongoClient>
  }
}
Aguayo answered 15/10, 2022 at 22:7 Comment(2)
also worked after restarting the vscode once done with these changesHazeghi
This is the only solution that worked for me with my SvelteKit app.Mlle
S
12

You should declare a global declared as interface in global.d.ts like this:

export interface global {}
declare global {
  var signin: ()=>string[]
}

The vscode gives correct code hints

Stellite answered 22/1, 2022 at 19:2 Comment(0)
H
8

You have to use the var keyword in declare global, and remove namespace NodeJS {.
Like this:

//globals.d.ts
import type { EventEmitter } from "events";
declare global {
    var myGlobal: EventEmitter;
}
/// <reference path="globals.d.ts" />
//index.ts
// reference needs to be at top of file
import { EventEmitter } from "events";
global.myGlobal = new EventEmitter();
global.myGlobal // EventEmitter type: EventEmitter
window.myGlobal // EventEmitter type: EventEmitter

Or if you don't have any imports in the .d.ts file:

//namedoesntmatter.d.ts
declare var a: string;
//index.ts
global.a = "Hello"
global.a //Hello type: string
window.a //Hello type: string
Hendrickson answered 18/9, 2021 at 20:8 Comment(0)
F
4

I too had the same issue. Fixed it by the below code.

declare global {
        function signin(): Promise<string[]>
}
Fenner answered 9/12, 2021 at 19:25 Comment(1)
Your answer could be improved by adding more information on what the code does and how it helps the OP.Ampoule
N
4

This is how I solved with Node.js V16+

// global.d.ts

export declare global {
   declare module globalThis {
      var MyVar: object;
   }
}
Niobous answered 26/8, 2022 at 15:26 Comment(0)
H
4

I tried everything I found here, but nothing worked.
Even stranger, VSCode showed NO TypeScript errors, but running tsc still threw:
TS7017: Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature.

After hours, I realised I forgot an "include": [ "src/app.ts" ] line in my tsconfig.json file.

Note to future self and for those who may have made the same mistake:
If you have explicitly provided one or more files in TypeScript's config with include, and that does not include the *.d.ts file, where you declared your globals, the build will fail with this error, even if VSCode shows no error (because it sees the global declaration, but TypeScript won't).

Hassi answered 20/11, 2022 at 12:37 Comment(0)
T
2

This is work for me during connect db with next 13.4

declare global {
  var mongoose: { conn: any; promise: any };
}
Thimblerig answered 16/7, 2023 at 4:47 Comment(0)
E
1

just declare variable by var keyword. like this:

// eslint-disable-next-line no-var
var hello = () => { console.log("hello world"); };
// eslint-disable-next-line no-var
var hi: () => number;

globalThis.hello();
globalThis.hi = () => 143;

enter image description here

You can declare variables in .d.ts files, too.

enter image description here

Electorate answered 16/9, 2021 at 12:49 Comment(0)
P
1

in my own case i didn't quite realize until later that the global namespace i declared was case sensitive.

instead of this. before my question was edited it was namespace NODEJS

declare global {
  namespace NODEJS {
    interface Global {
      signin(): string[]
    }
  }
}

it was supposed to be this

declare global {
  namespace NodeJS {
    interface Global {
      signin(): string[]
    }
  }
}

pay attention to NODEJS and NodeJS. After i made these changes, typescript was cool with it and it work the way i expected it to.

Pennate answered 19/9, 2021 at 8:33 Comment(2)
This doesn't work with the latest versions of @types/node.Pomp
And sorry I guess I hijacked your question :pPomp
W
0

Create the global.d.ts file and copy the following code:

declare global {
  declare module globalThis {
    var uniqueId: string;
  }
}

export {};

And finally, add "include": ["global.d.ts"] to the tsconfig.json file

Done!

Willed answered 14/8, 2023 at 8:42 Comment(0)
W
0

this fixes it

not global.signIn but

if (typeof (global as any).signIn === 'function') {
     (global as any).signIn = () => {}
}
Wilburn answered 29/11, 2023 at 15:50 Comment(0)
Z
0

Explanation:

I simply find the easiest solution by using globalThis like this:

(globalThis as any).myVariableKey = myVariableValue;

Because globalThis is at top level and you can add what you want, globalThis is always any.

Works on CommonJS compilation.

Documentation:

The globalThis global property contains the global this value, which is usually akin to the global object.

Solution:

(globalThis as any).signin = () => {}; // node global legacy

Way to use your own type:

Transform any as unknown as MyOwnType

type MyOwnType { // Custom properties };

(globalThis as unknown as MyOwnType).myDefinedPropertyInMyOwnType = value;
Zenda answered 12/1, 2024 at 15:26 Comment(0)
A
-2

The error you're encountering when trying to add a function to the global Node.js namespace in a TypeScript environment might be due to TypeScript's built-in type definitions being too restrictive. To address this, you can use declaration merging in a separate file to augment the Node.js types. Here's an example of how you can do this:

// Create a new file, for example, global.d.ts
declare global {
  namespace NodeJS {
    interface Global {
      signin(): string[];
    }
  }
}

By placing this code in a file with a .d.ts extension (such as global.d.ts), you can extend the global namespace without encountering type errors. This allows you to add custom functions to the global Node.js namespace in a TypeScript environment.

Advocation answered 14/1, 2024 at 8:25 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.