Type props chặt giúp bắt lỗi ngay lúc gọi component.
Generics — khi component làm việc với một kiểu dữ liệu bất kỳ mà vẫn giữ liên hệ giữa các prop. Ví dụ list nhận items: T[] và renderItem: (item: T) => ... — TS phải suy ra T từ items để renderItem được type đúng.
tsx
function List<T>({ items, renderItem }: {
items: T[]
renderItem: (item: T) => React.ReactNode
}) {
return <ul>{items.map(renderItem)}</ul>
}Discriminated union — khi props thay đổi theo "chế độ", tránh kiểu "tất cả optional" cho phép combo vô lý.
Một field kind làm discriminant, TS thu hẹp (narrow) các field còn lại.
tsx
type Props =
| { variant: 'link'; href: string }
| { variant: 'button'; onClick: () => void }
// Truyền variant='link' mà thiếu href → TS báo lỗi; onClick không tồn tại ở nhánh này.Lưu ý: union này khiến <button> không thể vừa có href vừa có onClick — chính là cái ta muốn.
Ngược lại nếu để cả hai optional, caller dễ truyền sai và lỗi chỉ lộ lúc runtime.