TypeScript

The SDK is fully typed and supports type-safe component props through TypeScript declaration merging.

Type-Safe Component Props

Register your component props for type-safe usage throughout your app:

types/dpage.d.ts
declare module '@dpage-ai/react-native-dpage' {
  interface ComponentPropsMap {
    ProductCard: { productId: string; showPrice?: boolean };
    UserProfile: { userId: string };
    CheckoutForm: { cartId: string; onComplete: () => void };
    PromoBanner: { campaignId?: string };
  }
}

Now DynamicComponent and useDynamicComponent will enforce the correct props:

TSX
// Type-safe! ✓
<DynamicComponent
  name="ProductCard"
  data={{ productId: '123' }}
/>

// TypeScript error: missing 'productId'
<DynamicComponent
  name="ProductCard"
  data={{ showPrice: true }}  // Error!
/>

// TypeScript error: wrong prop type
<DynamicComponent
  name="ProductCard"
  data={{ productId: 123 }}  // Error! productId should be string
/>

Hook Type Safety

The useDynamicComponent hook also benefits from the type declarations:

TSX
function MyScreen() {
  const { Component, loading, error } = useDynamicComponent('ProductCard');

  if (loading || !Component) return null;

  // Component props are inferred from ComponentPropsMap
  return (
    <Component
      productId="123"      // ✓ Required
      showPrice={true}     // ✓ Optional
    />
  );
}

Configuration Types

TSX
import type { DPageConfig } from '@dpage-ai/react-native-dpage';

const config: DPageConfig = {
  projectId: 'my-project',
  apiToken: 'dpage_live_xxx',
  fetch: {
    timeout: 10000,
    enabled: true,
  },
  cache: {
    ttl: 3600000,
    enabled: true,
  },
  logLevel: 'warn',
};

initDPage(config);

Event Handler Types

TSX
import { dpage } from '@dpage-ai/react-native-dpage';
import type {
  FetchStartEvent,
  FetchSuccessEvent,
  FetchErrorEvent,
  CacheEvent,
} from '@dpage-ai/react-native-dpage';

dpage.on('fetchStart', (e: FetchStartEvent) => {
  console.log(e.componentKey);
});

dpage.on('fetchSuccess', (e: FetchSuccessEvent) => {
  console.log(`${e.componentKey} loaded in ${e.durationMs}ms`);
});

dpage.on('fetchError', (e: FetchErrorEvent) => {
  console.error(e.error);
});

dpage.on('cacheHit', (e: CacheEvent) => {
  console.log(`Cache hit: ${e.componentKey}`);
});

Error Types

TSX
import {
  HttpError,
  FetchTimeoutError,
} from '@dpage-ai/react-native-dpage';

try {
  await refreshComponent('MyComponent');
} catch (error: unknown) {
  if (error instanceof HttpError) {
    // Type-safe access to HttpError properties
    console.log(`Status: ${error.status}`);
    console.log(`Status Text: ${error.statusText}`);
  } else if (error instanceof FetchTimeoutError) {
    // Type-safe access to FetchTimeoutError properties
    console.log(error.message);
  }
}

Custom Runtime Deps Types

deps.dpage.ts
import axios from 'axios';
import { format } from 'date-fns';
import CustomButton from './src/components/CustomButton';

// Explicitly type your dependencies
const apiDeps = {
  axios,
  format,
} as const;

const componentDeps = {
  CustomButton,
} as const;

// Type the export
export const customRuntimeDeps = {
  ...apiDeps,
  ...componentDeps,
} as const;

// Optional: Export the type for use elsewhere
export type CustomDeps = typeof customRuntimeDeps;

Strict Mode

The SDK is designed to work with TypeScript strict mode enabled. Ensure your tsconfig.json includes:

tsconfig.json
{
  "compilerOptions": {
    "strict": true,
    "strictNullChecks": true,
    "noImplicitAny": true
  }
}

Generic Components

Create generic wrapper components with proper typing:

TSX
import { DynamicComponent, ComponentPropsMap } from '@dpage-ai/react-native-dpage';

// Generic wrapper with loading skeleton
function DynamicWithSkeleton<K extends keyof ComponentPropsMap>({
  name,
  data,
  skeleton,
}: {
  name: K;
  data?: ComponentPropsMap[K];
  skeleton: React.ReactNode;
}) {
  return (
    <DynamicComponent
      name={name}
      data={data}
      renderLoading={() => skeleton}
    />
  );
}

// Usage - fully typed
<DynamicWithSkeleton
  name="ProductCard"
  data={{ productId: '123' }}
  skeleton={<ProductCardSkeleton />}
/>

Declaration File Location

Create your type declarations in one of these locations:

  • types/dpage.d.ts (recommended)
  • src/types/dpage.d.ts
  • @types/dpage.d.ts

Ensure the file is included in your tsconfig.json:

tsconfig.json
{
  "compilerOptions": {
    "typeRoots": ["./node_modules/@types", "./types"]
  },
  "include": ["src/**/*", "types/**/*"]
}

Best Practices

✅

Define all component props

Add every dynamic component to ComponentPropsMap for full type safety.

✅

Use strict mode

Enable TypeScript strict mode for best type checking.

✅

Type custom deps

Use 'as const' for runtime deps to preserve exact types.

✅

Handle null Component

Always check Component is not null before rendering.