TypeScript
Where the types come from, which ones exist, and the two that need narrowing.
@wajub/js ships its own definitions. There is no @types/ package to install and nothing to
configure. From 1.6.0 every framework wrapper re-exports the same types, so installing one of them
is enough: import type { PaymentSuccess } from '@wajub/react' works.
npm install @wajub/jsThe package declares three entry points, each with its own definitions.
| Import | Definitions | Side effect |
|---|---|---|
@wajub/js | dist/index.d.ts | Fetches the runtime on import |
@wajub/js/pure | dist/pure.d.ts | None until you call loadWajub() |
https://js.wajub.com | None, globals only | The whole runtime |
Everything worth importing
import type {
EmbeddedConfig,
PopupConfig,
CheckoutInstance,
PopupInstance,
ComponentConfig,
ComponentInstance,
ComponentsFactory,
ComponentType,
ConfirmPaymentOptions,
} from '@wajub/js';import type {
AppearanceConfig,
AppearanceVariables,
AppearanceRules,
AppearanceThemePreset,
AppearanceColorScheme,
AppearanceLabels,
CheckoutLayout,
CheckoutState,
EmbedBreakdown,
PaymentSuccess,
SessionPreview,
ComponentChangeEvent,
ComponentAddressValue,
AddressValue,
AddressMode,
PhoneFieldMode,
WajubError,
WajubErrorType,
} from '@wajub/js';import type {
WajubRuntime,
WajubSDK,
WajubClient,
WajubFactory,
WajubInitOptions,
LoadWajubOptions,
CreatePaymentParams,
CreatePaymentResult,
InitCheckoutOptions,
InitCheckoutResult,
} from '@wajub/js';Two more exist for compatibility: EmbedTheme, the deprecated theme shape, and WajubErrorShape,
the plain object behind a WajubError.
Two places where narrowing matters
The helpers can return null. Everything imported from @wajub/js resolves to null when
there is no window, which is what makes a server render safe. TypeScript will make you handle it.
import { loadWajub } from '@wajub/js/pure';
const runtime = await loadWajub();
if (!runtime) return;
const checkout = runtime.wajub.mount('#checkout', { sessionId });Once you hold the runtime, its methods are synchronous and never return null, so this is the
only check you need.
The error callbacks are not typed as WajubError. They receive
WajubError | Record<string, unknown>, because an error can also arrive as a raw payload from the
iframe. Narrow before reading code.
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);
},
});WajubError is declared in the types, but the module does not export it at runtime: an
import { WajubError } type checks, then comes out undefined or fails the bundle. Take the class from
what loadWajub() resolves to, as above. Everything else on this page is a type only import.
Server rendering
The three framework packages already handle the browser check for you, through WajubProvider.
Reach for the code below only when you wire @wajub/js yourself.
'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} />;
}Importing from /pure is what keeps the module free of side effects, so the bundler does not pull
a CDN fetch into your server build.
Typing the CDN globals
With the script tag and no npm package, wajub, Wajub and WajubError sit on window. The
package declares them globally, so installing it as a development dependency types a project that
never bundles it, once TypeScript loads those declarations: a project that never imports the package
has to name it, with /// <reference types="@wajub/js" /> at the top of one file or
"types": ["@wajub/js"] in compilerOptions.
declare global {
interface Window {
wajub: WajubSDK;
Wajub: WajubFactory;
WajubError: typeof WajubError;
}
}A remote reference path does not work
https://js.wajub.com/wajub-checkout.d.ts is served, but TypeScript only resolves
/// <reference path> against the local file system. Download the file next to your code and
reference that path, or add @wajub/js as a development dependency and let the compiler find
it on its own. The second is less to maintain.
Framework types
Each wrapper re-exports everything above, and React and Vue add their own prop types.
| Package | Adds |
|---|---|
@wajub/react | WajubProviderProps, CheckoutEmbedProps, ComponentEmbedProps, WajubContextValue |
@wajub/vue | The same four, plus WAJUB_INJECTION_KEY and, from 1.6.0, WajubRuntimeRef |
@wajub/svelte | WajubContextValue and, from 1.6.0, WajubRuntimeStore |
The Svelte components are not typed
Every component in @wajub/svelte is declared as a bare SvelteComponent, and the package
exports no prop types. Your editor will not complete a prop and svelte-check will not catch a
misspelled one. Details and the workaround are on Svelte.