[Typescript] Global Scope
Define function / variable in global scope
globalThis.myFunc = () => true; // doesn't compile
globalThis.myVar = 1; // doesn't compile
it("Should let you call myFunc without it being imported", () => {
expect(myFunc()).toBe(true);
type test1 = Expect<Equal<typeof myFunc, () => boolean>>;
});
it("Should let you access myVar without it being imported", () => {
expect(myVar).toBe(1);
type test1 = Expect<Equal<typeof myVar, number>>;
});
To enable it, we can do:
declare global {
function myFunc(): boolean;
var myVar: number;
}
This affects the global scope, it doesn't matter which file you put those code, it just affect all the global scope.
There are some limitations:
- for the variable, you cannot use `
const, let
`, you can only usevar
- You cannot put implementation into the function.
Type global Window
window.makeGreeting = () => "Hello!"; // doesn't compile
it("Should let you call makeGreeting from the window object", () => {
expect(window.makeGreeting()).toBe("Hello, world!");
type test1 = Expect<Equal<typeof window.makeGreeting, () => string>>;
});
it("Should not be available on globalThis", () => {
expect(
// @ts-expect-error
globalThis.makeGreeting
).toBe(undefined);
});
We can find the Window declarion:
interface Window extends EventTarget, AnimationFrameProvider, GlobalEventHandlers, WindowEventHandlers, WindowLocalStorage, WindowOrWorkerGlobalScope, WindowSessionStorage {
/** @deprecated This is a legacy alias of `navigator`. */
readonly clientInformation: Navigator;
..
}
But we cannot just add our function directly into that .d.ts
file. What we can do is using declarion merging:
declare global {
function myFunc(): boolean;
var myVar: number;
interface Window {
makeGreeting: () => string;
}
}
The Window
we diefined in global
will merge with the interface Window form .d.ts
file.
Typing process.env
https://www.typescriptlang.org/docs/handbook/namespaces.html#handbook-content
process.env.MY_ENV_VAR = "Hello, world!"; // doesn't compile
it("Should be declared as a string", () => {
expect(process.env.MY_ENV_VAR).toEqual("Hello, world!");
});
it("Should NOT have undefined in the type", () => {
const myVar = process.env.MY_ENV_VAR;
type tests = [Expect<Equal<typeof myVar, string>>];
});
We need to use NodeJS namespace
:
declare global {
namespace NodeJS {
interface ProcessEnv {
MY_ENV_VAR: string;
}
}
}
namespace mainly used by libraries, so that different libraries won't conflict with each others.
Also with namespace, you cannot access ProcessEnv
directly, you have to do NodeJS.ProcessEnv
.