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. Every framework wrapper re-exports the same types, so installing one of them is enough.
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,
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 { WajubError } from '@wajub/js';
await mount('#checkout', {
sessionId,
onError: (error) => {
if (error instanceof WajubError) {
report(error.code, error.retryable);
return;
}
report('unknown_error', false);
},
});WajubError is exported as a value, not only a type, so instanceof works. 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.
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
React and Vue export their own prop types alongside everything above.
| Package | Adds |
|---|---|
@wajub/react | WajubProviderProps, CheckoutEmbedProps, ComponentEmbedProps, WajubContextValue |
@wajub/vue | The same four, plus WAJUB_INJECTION_KEY |
@wajub/svelte | WajubContextValue only |
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.