I am trying to use globalThis in Typescript and I would like some suggestions on how to write it in a better way.
Current implementation is like this:
Create a file types/global.d.ts and add inside
interface Global {
foo: string
}
declare let foo: Global["foo"];
in tsconfig.json add
"files": [
"types/global.d.ts"
]
Then in order to set the value of foo
use
(globalThis as any).foo = "The value of foo"
What I don't like with this approach is first the boilerplate needed (but I think this cannot be avoided) and second the (globalThis as any).foo =
expression
Applies to TypeScript 4.3+
Element implicitly has an
any
type because typetypeof globalThis
has no index signature. ts(7017)
declare global {
function myFunction(): boolean;
var myVariable: number;
}
globalThis.myFunction = () => true;
globalThis.myVariable = 42;
var
(do not use let
or const
).See the discussion on TypeScript issue 30139.
Traditionally, the way to specify a TypeScript declare-block in a Node.js context was as follows:
// Does not work as of October 2021 (TypeScript 4.3+)
declare global {
module NodeJS {
interface Global {
myFunction(): boolean;
myVariable: number;
}
}
}
Note that this error will be suppressed if the TypeScript setting noImplicitAny
is set to false
. It is recommended to enable noImplicitAny
for better type checking.
My answer is based on the one by Edward Casanova. I was about to edit it, but there are still quite a few differences to the code that works for me, plus I can now give some additional information on this.
This is based on TypeScript 4.3.5
// typings/globals.d.ts (depending on your tsconfig.json)
interface Person {
name: string
}
export declare global {
var someString: string
var globalPerson: Person
}
This does not work without at least one export
(or import
) keyword. This turns this file into an ES module, which is necessary for this to work this way. You don't need to export
declare global
if you can export something else instead:
export interface Person { /* ... */ }
declare global { /* ... */ }
The code above adds types for the following handles:
someString
window.someString
globalThis.someString
globalPerson.name
window.globalPerson.name
globalThis.globalPerson.name
On the other side, the following is possible, but the result is different:
export declare global {
let someLetString: string
const someConstString: string
}
This only adds types for the following handles:
someLetString
someConstString
As expected, you cannot assign any value to someConstString
. This might be useful for some older JS libraries that add the functionality to the global scope instead of exporting it. Libraries still can assign values to const
in this case because it's just a type, not a real const
. This const
is only known to TypeScript code. But be aware that let
and const
don't add properties to the global objects window
and globalThis
. So, var
might be the better choice here after all.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With