TypeScript Usage
This guide covers TypeScript usage with Flowfull Client.
Type Safety
Flowfull Client is written in TypeScript and includes full type definitions out of the box. No additional @types packages are needed.
Typed API Calls
Use TypeScript generics to type your API responses:
typescript
import { createFlowfull } from '@pubflow/flowfull-client';
const api = createFlowfull('https://api.example.com');
// Define your types
interface User {
id: string;
name: string;
email: string;
role: 'admin' | 'user' | 'guest';
createdAt: string;
}
// Type the response
const users = await api.get<User[]>('/users');
// users is typed as User[]
const user = await api.get<User>('/users/123');
// user is typed as UserTyped POST Requests
typescript
interface CreateUserInput {
name: string;
email: string;
password: string;
role?: 'admin' | 'user';
}
interface CreateUserResponse {
id: string;
name: string;
email: string;
role: string;
createdAt: string;
}
const newUser = await api.post<CreateUserResponse>(
'/users',
{
name: 'John Doe',
email: 'john@example.com',
password: 'password123',
role: 'user'
} as CreateUserInput
);
// newUser is typed as CreateUserResponse
console.log(newUser.id);Typed Query Builder
typescript
interface User {
id: string;
name: string;
email: string;
status: 'active' | 'inactive';
role: 'admin' | 'user' | 'guest';
}
const users = await api.query<User>('/users')
.filter('status', 'active')
.filter('role', 'admin')
.orderBy('name', 'asc')
.limit(10)
.execute();
// users is typed as User[]Type Inference
Flowfull Client provides excellent type inference:
typescript
// Type is inferred from the generic
const user = await api.get<User>('/users/123');
// TypeScript knows user has these properties
console.log(user.name); // ✅ OK
console.log(user.email); // ✅ OK
console.log(user.invalid); // ❌ Error: Property 'invalid' does not existError Handling with Types
typescript
import { FlowfullError } from '@pubflow/flowfull-client';
try {
const users = await api.get<User[]>('/users');
console.log(users);
} catch (error) {
if (error instanceof FlowfullError) {
console.error('Status:', error.status);
console.error('Message:', error.message);
console.error('Data:', error.data);
} else {
console.error('Unknown error:', error);
}
}Generic Components
Create reusable components with generics:
typescript
import { useState, useEffect } from 'react';
import { api } from '../lib/api';
interface ListProps<T> {
endpoint: string;
renderItem: (item: T) => React.ReactNode;
}
function List<T extends { id: string }>({ endpoint, renderItem }: ListProps<T>) {
const [items, setItems] = useState<T[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function fetchItems() {
try {
const data = await api.get<T[]>(endpoint);
setItems(data);
} catch (error) {
console.error('Error fetching items:', error);
} finally {
setLoading(false);
}
}
fetchItems();
}, [endpoint]);
if (loading) return <div>Loading...</div>;
return (
<ul>
{items.map(item => (
<li key={item.id}>{renderItem(item)}</li>
))}
</ul>
);
}
// Usage
interface User {
id: string;
name: string;
email: string;
}
function UserList() {
return (
<List<User>
endpoint="/users"
renderItem={(user) => (
<div>
<strong>{user.name}</strong>
<span>{user.email}</span>
</div>
)}
/>
);
}Custom Hooks with Types
typescript
import { useState, useEffect } from 'react';
import { api } from '../lib/api';
function useApi<T>(endpoint: string) {
const [data, setData] = useState<T | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
async function fetchData() {
try {
const result = await api.get<T>(endpoint);
setData(result);
} catch (err: any) {
setError(err.message);
} finally {
setLoading(false);
}
}
fetchData();
}, [endpoint]);
return { data, loading, error };
}
// Usage
interface User {
id: string;
name: string;
email: string;
}
function UserProfile({ userId }: { userId: string }) {
const { data: user, loading, error } = useApi<User>(`/users/${userId}`);
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
if (!user) return <div>User not found</div>;
return (
<div>
<h1>{user.name}</h1>
<p>{user.email}</p>
</div>
);
}Strict Type Checking
Enable strict type checking in your tsconfig.json:
json
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true
}
}Next Steps
- API Reference - Complete API documentation
- Examples - See TypeScript examples in action
- Making API Calls - Learn more about API calls