Roadmap › TypeScript — Types, Generics and Real-World Patterns › Module: Advanced Types
Lessons in this course (9)
9. Typing real API calls in Angular and React
Advanced★ Must knowLesson 9 of 9
typescript
// models.ts — generated from the backend OpenAPI or written by hand
export interface OrderDto { id: number; orderDate: string; status: OrderStatus; total: number; }
// Angular service
@Injectable({ providedIn: "root" })
export class OrdersApi {
private http = inject(HttpClient);
list(page: number) { return this.http.get<Paged<OrderDto>>("/api/orders", { params: { page } }); }
}
// React with fetch + runtime validation (types alone don't check the server response)
import { z } from "zod";
const OrderSchema = z.object({ id: z.number(), orderDate: z.string(), status: z.enum(["draft", "submitted", "shipped"]), total: z.number() });
type Order = z.infer<typeof OrderSchema>;
async function getOrders(): Promise<Order[]> {
const res = await fetch("/api/orders");
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return z.array(OrderSchema).parse(await res.json()); // throws if the API shape changed
}
// Typed React props and state
type Props = { orders: Order[]; onSelect: (id: number) => void };
function OrderTable({ orders, onSelect }: Props) { /* … */ }
const [selected, setSelected] = useState<Order | null>(null);Interview tip:
http.get<T>()andas Tare promises to the compiler, not checks. Mention generating types from OpenAPI and validating at the boundary.