Search code examples
typescriptpaypal

PayPal SDK with TypeScript - paypal.Buttons() is possibly undefined?


I'm using the PayPal SDK in my SvelteKit app, using TypeScript. I'm running into the issue where running their paypal.Buttons method like documented always results in a TypeScript error.

For example this is the code from their README:

import { loadScript } from "@paypal/paypal-js";

let paypal;

try {
  paypal = await loadScript({ clientId: "test" });
} catch (error) {
  console.error("failed to load the PayPal JS SDK script", error);
}

if (paypal) {
  try {
    await paypal.Buttons().render("#your-container-element");
  } catch (error) {
    console.error("failed to render the PayPal Buttons", error);
  }
}

But this gives the error Cannot invoke an object which is possibly undefined on line 13, on paypal.Buttons(). How can I call their method without having this error always show up in my linter's output? I don't know if their README needs to be updated, or if their code needs to be fixed to return better types?


Solution

  • Unless I'm missing any debugging details or further specific typings in the PayPayl SDK, using optional chaining as follows works perfectly fine. Pay attention to the syntax: ?.().

    type Paypal = {
      Buttons?(): {render(): any};
    };
    
    const paypal: Paypal = {
      Buttons() {
        return {render() {}};
      }
    };
    
    paypal.Buttons?.().render();
    

    TypeScript Playground


    Take a look at the compiled JS output.

    "use strict";
    var _a;
    const paypal = {
        Buttons() {
            return { render() { } };
        }
    };
    (_a = paypal.Buttons) === null || _a === void 0 ? void 0 : _a.call(paypal).render();