Aller au contenu

TypeScript

L'origine des types, les types disponibles et les deux qui doivent être affinés.

@wajub/js fournit ses propres définitions. Aucun package @types/ à installer ni aucune configuration à effectuer. Les packages de framework exportent les mêmes types. Il suffit donc d'en installer un : import type { PaymentSuccess } from '@wajub/react' fonctionne.

npm install @wajub/js

Chaque point d'entrée est typé.

ImportTypesEffet de bord
@wajub/jsInclusCharge Wajub.js lors de l'importation
@wajub/js/pureInclusAucun avant l'appel de loadWajub()
https://js.wajub.comVariables globales uniquement, voir plus basCharge Wajub.js

Tous les éléments utiles à importer

Configuration et instances
import type {
  EmbeddedConfig,
  PopupConfig,
  CheckoutInstance,
  PopupInstance,
  ComponentConfig,
  ComponentFieldsConfig,
  ComponentInstance,
  ComponentsFactory,
  ComponentType,
  ConfirmPaymentOptions,
} from '@wajub/js';
Styles, payloads et erreurs
import type {
  AppearanceConfig,
  AppearanceVariables,
  AppearanceRules,
  AppearanceThemePreset,
  AppearanceColorScheme,
  AppearanceLabels,
  CheckoutLayout,
  CheckoutState,
  EmbedBreakdown,
  PaymentSuccess,
  SessionPreview,
  ClientSignals,
  ComponentChangeEvent,
  ComponentRedirectEvent,
  ComponentStateChangeEvent,
  ComponentEventMap,
  InheritSource,
  ComponentAddressValue,
  AddressValue,
  AddressMode,
  CollectAddressMode,
  PhoneFieldMode,
  WajubError,
  WajubErrorType,
} from '@wajub/js';
Environnement d'exécution et client
import type {
  WajubRuntime,
  WajubSDK,
  WajubClient,
  WajubFactory,
  WajubInitOptions,
  CreatePaymentParams,
  CreatePaymentResult,
  InitCheckoutOptions,
  InitCheckoutResult,
} from '@wajub/js';

Deux cas où l'affinage des types est important

Les helpers peuvent renvoyer null. Tout élément importé depuis @wajub/js renvoie null en l'absence de window. Le rendu serveur reste ainsi sûr. TypeScript vous oblige à traiter ce cas. Deux exceptions, componentEstimatedHeight() et componentReserveHeight(), sont synchrones et renvoient un nombre sur le serveur aussi.

Aucune erreur sur le serveur
import { loadWajub } from '@wajub/js/pure';

const runtime = await loadWajub();
if (!runtime) return;

const checkout = runtime.wajub.mount('#checkout', { sessionId });

Une fois l'environnement d'exécution obtenu, ses méthodes sont synchrones et ne renvoient jamais null. Cette vérification est donc la seule nécessaire.

Les callbacks d'erreur ne sont pas typés comme WajubError. Ils reçoivent WajubError | Record<string, unknown>. Affinez le type avant de lire code.

Affiner le type d'une erreur
import { loadWajub, mount } from '@wajub/js';

const runtime = await loadWajub();

await mount('#checkout', {
  sessionId,
  onError: (error) => {
    if (runtime && error instanceof runtime.WajubError) {
      report(error.code, error.retryable);
      return;
    }
    report('unknown_error', false);
  },
});

Prenez la classe WajubError dans ce que renvoie loadWajub(), comme ci-dessus, et non dans un import de @wajub/js. Tous les autres éléments de cette page sont importés uniquement comme types.

Les données des événements

on(event, fn) et off(event, fn) typent la donnée de chaque événement qu'émet un composant, avec ComponentEventMap : statechange transmet un ComponentStateChangeEvent, redirect un ComponentRedirectEvent, resize un { height }. Les callbacks correspondants de ComponentConfig, onStateChange, onResize et onRedirect, sont typés de la même façon.

Lire la redirection
component.on('redirect', ({ url, method }) => {
  // La page part juste après, un beacon y survit, un fetch peut-être pas.
  navigator.sendBeacon('/analytics/left-for-provider', JSON.stringify({ host: new URL(url).host, method }));
});

Rendu serveur

Avec un package de framework, vous n'avez rien à faire. Le code ci-dessous sert à intégrer vous-même @wajub/js.

React sans @wajub/react
'use client';

import { useEffect, useRef } from 'react';
import { loadWajub } from '@wajub/js/pure';
import type { CheckoutInstance } from '@wajub/js';

export function Checkout({ sessionId }: { sessionId: string }) {
  const host = useRef<HTMLDivElement>(null);
  const instance = useRef<CheckoutInstance | null>(null);

  useEffect(() => {
    loadWajub().then((runtime) => {
      if (!runtime || !host.current) return;
      instance.current = runtime.wajub.mount(host.current, { sessionId });
    });

    return () => instance.current?.destroy();
  }, [sessionId]);

  return <div ref={host} />;
}

Importez depuis /pure, pour que l'importation du module ne fasse rien sur le serveur.

Pour garder la place d'un champ de paiement dans ce rendu serveur, donnez à son conteneur componentEstimatedHeight(type, variant, fields) comme min-height, la même sur le serveur et à l'hydratation. Dans le navigateur, remettez ce min-height à 0 juste avant de monter le champ avec loader: 'skeleton'.

Typer les variables globales du CDN

Avec la balise script et sans package npm, wajub, Wajub et WajubError sont disponibles sur window. Pour les typer, installez @wajub/js comme dépendance de développement et, comme votre code ne l'importe jamais, nommez-le avec /// <reference types="@wajub/js" /> en tête d'un fichier ou "types": ["@wajub/js"] dans compilerOptions.

Déjà déclarés pour vous
declare global {
  interface Window {
    wajub: WajubSDK;
    Wajub: WajubFactory;
    WajubError: typeof WajubError;
  }
}

Types des frameworks

Chaque package de framework exporte tous les éléments ci-dessus, et y ajoute ses propres types.

PackageAjouts
@wajub/reactWajubProviderProps, CheckoutEmbedProps, ComponentEmbedProps, WajubContextValue
@wajub/vueLes quatre mêmes, avec WajubRuntimeRef
@wajub/svelteWajubContextValue, WajubRuntimeStore, ComponentEmbedProps, TypedComponentProps et SessionIdSource
@wajub/angularWajubOptions, SessionIdSource et WajubConfirmPayment. Les inputs et les outputs sont typés sur les classes des composants, que lit la vérification des types de templates d'Angular

Que pensez-vous de ce contenu ?