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:
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:
// 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:
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
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
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
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
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:
{
"compilerOptions": {
"strict": true,
"strictNullChecks": true,
"noImplicitAny": true
}
}Generic Components
Create generic wrapper components with proper typing:
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:
{
"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.