Borislav Hadzhiev
Thu Mar 10 2022·3 min read
Photo by Erik Mclean
The error "Element implicitly has an 'any' type because type 'typeof
globalThis' has no index signature" occurs when we try to access a property that
doesn't exist on the global
object. To solve the error, extend the global
object and add types for the necessary properties.
Here is an example of how the error occurs.
// ⛔️ Error: Element implicitly has an 'any' // type because type 'typeof globalThis' // has no index signature.ts(7017) global.hello = 'world';
We tried to access a property that doesn't exist on the global
object and got
the error.
To solve this, we have to add typings for the properties and methods we intend
to access on the global
object.
In your src
directory, create a types
directory that contains the following
index.d.ts
file:
/* eslint-disable no-var */ declare global { var example: string; function sum(a: number, b: number): number; } export {};
We added an example
property that has a type of string
and a sum
method.
Make sure to use the var
keyword to add typings for properties you intend to
set and use in other files.
You need to add the names and types of all of the properties you intend to
access on the global
object.
For example, if you don't know the type of the specific property and want to
turn off type checking, set it to any
.
/* eslint-disable no-var */ declare global { var example: string; function sum(a: number, b: number): number; } export {};
Now, I'm able to set and access the specified property on the global
object
without getting any errors.
global.example = 'hello world'; global.sum = function (a: number, b: number) { return a + b; }; console.log(global.example); // 👉️ "hello world" console.log(global.sum(15, 25)); // 👉️ 40
Note that you might still be getting an error in your terminal if you are using ts-node.
The problem is with ts-node
not recognizing local declaration files.
To solve this, use the --files
flag with your ts-node
command, so instead of
ts-node ./src/index.ts
you should run ts-node --files ./src/index.ts
.
I'm using nodemon
with ts-node
and here are the contents of my
nodemon.json
file.
{ "watch": ["src"], "ext": ".ts,.js", "ignore": [], "exec": "ts-node --files ./src/index.ts" }
After adding the --files
flag (only required if using ts-node
), restart your
server and you should be good to go.
Note that this makes the sum
function and the example
property accessible
directly (globally) and on the global
object.
global.example = 'hello world'; global.sum = function (a: number, b: number) { return a + b; }; console.log(global.example); // 👉️ "hello world" console.log(global.sum(15, 25)); // 👉️ 40 console.log(example); // 👉️ "hello world" console.log(sum(5, 15)); // 👉️ 20
If you are still getting an error in your IDE, try adding the path to your
types
directory to your tsconfig.json
file.
{ "compilerOptions": { // ... rest "typeRoots": ["./node_modules/@types", "./src/types"] } }
We used the export {}
line in our index.d.ts
file to mark it as an external
module. A module is a file that contains at least 1 import
or export
statement. We are required to do that to be able to augment the global scope.
index.d.ts
file according to your use case.You should add the names (and types) of all of the properties you intend to
access on the global
object.
/* eslint-disable no-var */ declare global { var example: any; // 👈️ disables type checking for property function sum(a: number, b: number): number; } export {};
The provided file simply adds an example
property with a type of any
and a
sum
method, which is most likely not what you need.
TypeScript looks for .d.ts
files in the same places it looks for your regular
.ts
files, which is determined by the include
and exclude
settings in your
tsconfig.json
file.
TypeScript will merge the typings you declared on the global object with the original typings, so you will be able to access properties and methods from both declarations.