[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:

  1. for the variable, you cannot use `const, let`, you can only use var
  2. 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 ProcessEnvdirectly, you have to do NodeJS.ProcessEnv.

 

posted @ 2023-02-06 21:04  Zhentiw  阅读(21)  评论(0编辑  收藏  举报