Cả hai đều mô tả shape (cấu trúc) của object; khác nhau ở những gì làm được ngoài object và khả năng gộp khai báo.
typescript
// chỉ type làm được
type Id = string | number // union
type Pair = [number, number] // tuple
type Keys = keyof User // đặt tên cho union các key: 'id' | 'name' | ...
// cả hai đều làm được — type chỉ gọn hơn
type Fn = (a: number) => void
interface FnI { (a: number): void } // call signature
// chỉ interface làm được — declaration merging
interface Window { myApp: App } // gộp vào Window có sẵn
interface Window { analytics: Tracker } // gộp tiếp — không lỗitypescript
// type khai báo trùng tên là LỖI
type A = { x: number }
type A = { y: number } // Error: Duplicate identifier 'A'interface | type | |
|---|---|---|
| Mô tả object | có | có |
| Union / tuple / conditional | không | có |
| Gộp khai báo (merging) | có | không |
| Mở rộng | extends | & |
| Thông báo lỗi | thường ngắn gọn hơn | có thể bung dài |
Quy tắc thực dụng:
- interface cho object công khai của thư viện hoặc props của component — vì người dùng có thể mở rộng, và lỗi dễ đọc hơn.
- type cho union, tuple, hàm, và mọi kiểu suy ra từ kiểu khác.
Lưu ý — con dao hai lưỡi: declaration merging là ưu điểm khi cần mở rộng type của thư viện, nhưng là nhược điểm trong code ứng dụng — một interface cùng tên ở file khác có thể âm thầm thêm thuộc tính mà không ai để ý.