[FIXED] Web OTP API Typescript Typings issue – Missing Types in TypeScript

Issue

I am following instructions available on https://web.dev/web-otp/ to implement Web OTP API in my Angular App. But when adding below code it throws error:

const content = await window.navigator['credentials'].get({
        otp: { transport: ['sms'] },
        signal: abortController.signal
      });

Here’s the error message:

Error   TS2769  (TS) No overload matches this call.
  Overload 1 of 2, '(options?: CredentialRequestOptions): Promise<CredentialType>', gave the following error.
    Argument of type '{ otp: { transport: string[]; }; signal: AbortSignal; }' is not assignable to parameter of type 'CredentialRequestOptions'.
      Object literal may only specify known properties, and 'otp' does not exist in type 'CredentialRequestOptions'.
  Overload 2 of 2, '(options?: CredentialRequestOptions): Promise<Credential>', gave the following error.
    Argument of type '{ otp: { transport: string[]; }; signal: AbortSignal; }' is not assignable to parameter of type 'CredentialRequestOptions'.
      Object literal may only specify known properties, and 'otp' does not exist in type 'CredentialRequestOptions'.

I have @types/webappsec-credential-management added, but I believe its not yet updated to support otp.

Is there any workaround?

Solution

This is how I solved the issue:

Created a new folder with name typings and added it to typeRoots in tsconfig.json

"typeRoots": [
      "typings",
      "node_modules/@types"
    ],

Created a new file polyfills.d.ts in folder typings and added below contents to the file:

interface CredentialRequestOptions {
  otp: OTPOptions;
}

interface OTPOptions {
  transport: string[];
}

If you are wondering why I havent added other properties to the interface, that’s because I already have:

"types": [
      "@types/webappsec-credential-management"
    ]

And "@types/webappsec-credential-management": "^0.5.1", in packages.json.

The support of OTP is yet to be added, and to addres the missing otp property I took benefit of TypeScript’s feature Declaration Merging, now TypeScript compiler merges these two separate declarations (one defined in node_modules/@types and other in typings) declared with the same name into a single definition.

For further reading: https://justintimecoder.com/how-to-polyfil-missing-types-in-typescript/

Update

Below is the function that you can add to your Angular Component to make it work in your app:

async otpRequest() {
    if ('OTPCredential' in window) {

      const abortController = new AbortController();
      let timer = setTimeout(() => {
        abortController.abort();
      }, 10 * 1000);

      let o: CredentialRequestOptions = {
        otp: { transport: ['sms'] },
        signal: abortController.signal
      };

      const content = await window.navigator['credentials'].get(o);

      //do what ever you want to do with the received code, probably send it to server
    }
  }

Call this function, then make http request to send sms code on user’s mobile device.

Answered By – Naveed Ahmed

Answer Checked By – Marilyn (Easybugfix Volunteer)

Leave a Reply

(*) Required, Your email will not be published