Reputation: 1088
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
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:
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
Reputation: 2546
this fixes it
not global.signIn
but
if (typeof (global as any).signIn === 'function') {
(global as any).signIn = () => {}
}
Upvotes: 0
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
Reputation: 31
This is work for me during connect db with next 13.4
declare global {
var mongoose: { conn: any; promise: any };
}
Upvotes: 2
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
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
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
Reputation: 845
Below is an example for Node v16
// globals.d.ts
declare module globalThis {
var signin: () => string[];
}
Upvotes: 53
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
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
Reputation: 43
I too had the same issue. Fixed it by the below code.
declare global {
function signin(): Promise<string[]>
}
Upvotes: 4
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
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
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;
You can declare variables in .d.ts
files, too.
Upvotes: 1