Mhd
Mhd

Reputation: 1088

type 'typeof globalThis' has no index signature

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

Upvotes: 78

Views: 67428

Answers (14)

Shim-Sao
Shim-Sao

Reputation: 2126

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;

Upvotes: 2

Mr Heelis
Mr Heelis

Reputation: 2546

this fixes it

not global.signIn but

if (typeof (global as any).signIn === 'function') {
     (global as any).signIn = () => {}
}

Upvotes: 0

Mohamad
Mohamad

Reputation: 56

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!

Upvotes: 2

Rezzak Dev
Rezzak Dev

Reputation: 31

This is work for me during connect db with next 13.4

declare global {
  var mongoose: { conn: any; promise: any };
}

Upvotes: 2

frzsombor
frzsombor

Reputation: 2550

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).

Upvotes: 4

Cool Lab
Cool Lab

Reputation: 379

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>
  }
}

Upvotes: 28

passionateLearner
passionateLearner

Reputation: 808

This is how I solved with Node.js V16+

// global.d.ts

export declare global {
   declare module globalThis {
      var MyVar: object;
   }
}

Upvotes: 7

Willian Arana
Willian Arana

Reputation: 845

Below is an example for Node v16

// globals.d.ts
declare module globalThis {
    var signin: () => string[];
}

Upvotes: 53

umuoy1
umuoy1

Reputation: 121

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

Upvotes: 12

IRONM00N
IRONM00N

Reputation: 1325

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";

Upvotes: 88

jonathan
jonathan

Reputation: 43

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

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

Upvotes: 4

jackssrt
jackssrt

Reputation: 446

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

Upvotes: 9

Mhd
Mhd

Reputation: 1088

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.

Upvotes: 1

James Fancy
James Fancy

Reputation: 39

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

Upvotes: 1

Related Questions