Adding Screen Wake Lock API to Navigator in TypeScript

I was experimenting with the Screen Wake Lock API and decided to also experiment with
Visual Studio Code’s JS Doc and Typescript checking.

I’ve used TypeScript to type check JavaScript before, and it works pretty good for basic stuff like browser interfaces and interfaces that are specific to your application. It’s not something I would put all my trust in, but it’s a good augmentation when working with JavaScript. Anyways, when I tried to access navigator.wakeLock I got this type error…

Property 'wakeLock' does not exist on type 'Navigator'.ts(2339)

When I looked at the global type definition for Navigator it looked like the wakeLock interface had not yet been added. This makes sense because Wake Lock was only recently introduced and as of October 2020 its specification is still in draft.

So using the lib.dom.d.ts library as reference, I thought I would try adding my own type definition for this new interface. Note that you can also see these definitions in Visual Studio Code by Right Clicking “navigator” and selecting “Show Type Definition”.

What I needed to do was to extend the Navigator interface so it had the new “wakeLock” interface on it. To do that, I defined the Navigator interface in my project’s d.ts file so I can extend the properties of Navigator. Then I defined types for WakeLock, WakeLockSentinel, and the Navigator.wakeLock function. Here’s my final implementation…

interface BaseWebLockSentinelEventMap {
  "onrelease": Event;
}

type WakeLockSentinel {
  readonly released: Boolean;
  readonly type: string;
  release() : Promise
  addEventListener(type: K, listener: (this: Event, ev: BaseWebLockSentinelEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
  addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
  removeEventListener(type: K, listener: (this: Event, ev: BaseWebLockSentinelEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
  removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
}

type WakeLockRequestType = "screen"

interface Navigator {
  wakeLock: {
    request: (type: WakeLockRequestType) => Promise
  }
}

And the type hinting works in JavaScript now!

For future reference I was able to enable TypeScript type checking in JavaScript by adding a tsconfig.json file to my project root…

{
  "compilerOptions": {
    "checkJs": true,
    "allowJs": true,
    "noEmit": true
  }
}

And then creating a global type definition file named types.d.ts in the project root as well. That’s where I put the new interface definition.