Tạo TypeScript Types từ JSON — đúng cách
Tạo type từ một response mẫu chỉ mất vài giây. Nhưng để có type thật sự đáng tin cậy, bạn cần quyết định thêm vài điều: trường nào là optional, trường nào là nullable, đặt tên thế nào, và làm sao đảm bảo API giữ đúng cam kết khi chạy thực tế.
Bắt đầu từ dữ liệu thực
Dán một response vào công cụ JSON to TypeScript và bạn sẽ nhận được interface cho mọi object lồng nhau. Tuy nhiên, một mẫu chỉ phản ánh một cấu trúc, nên hãy dán một mảng gồm nhiều object thực tế: công cụ sẽ gộp chúng lại và đánh dấu các trường bị thiếu ở một số object là optional.
[
{ "id": 1, "name": "Ada", "email": "ada@example.com", "team": { "id": 7, "name": "Core" } },
{ "id": 2, "name": "Grace", "email": null }
]
interface User {
id: number;
name: string;
email: string | null;
team?: Team;
}
interface Team {
id: number;
name: string;
}
Optional không đồng nghĩa với nullable
team?: Team nghĩa là key có thể không tồn tại. email: string | null nghĩa là key luôn có mặt nhưng có thể là null. API dùng hai trường hợp này khác nhau và code của bạn kiểm tra chúng cũng khác nhau ('team' in user so với user.email === null), vì vậy hãy giữ sự phân biệt này thay vì biến mọi thứ thành ?: … | null.
Siết chặt những gì mẫu dữ liệu không thể cho biết
- Literal union — trường
statusthấy là"active"sẽ thànhstring; hãy thay bằng'active' | 'paused' | 'deleted'theo tài liệu API. - Ngày tháng được trả về dưới dạng chuỗi ISO. Hãy khai báo kiểu
stringvà parse ở điểm tiếp nhận dữ liệu — đừng giả vờ đó là objectDate. - ID — các ID số lớn (vượt quá 253) bị mất độ chính xác trong JavaScript; vì lý do này, nhiều API gửi chúng dưới dạng chuỗi.
- Mảng rỗng sẽ thành
unknown[]hoặcany[]; hãy tự điền kiểu phần tử.
Type biến mất khi chạy
TypeScript chỉ kiểm tra code của bạn, không kiểm tra dữ liệu. Nếu API thay đổi, trình biên dịch sẽ không nhận ra. Hãy kiểm tra response tại điểm tiếp nhận:
- Tạo schema từ cùng các mẫu dữ liệu bằng JSON to JSON Schema.
- Chỉnh sửa lại — các trường bắt buộc, enum, định dạng như
date-time— và thử các payload thực tế trong JSON Schema Validator. - Kiểm tra trong ứng dụng bằng thư viện như Ajv, và tạo type từ schema (JSON Schema to TypeScript) để chỉ có một nguồn sự thật duy nhất.
import Ajv from 'ajv';
const ajv = new Ajv();
const validate = ajv.compile(userSchema);
const data = await res.json();
if (!validate(data)) throw new Error('Unexpected API response: ' + ajv.errorsText(validate.errors));
Các thư viện như Zod hoặc Valibot làm điều tương tự với schema được viết ngay trong TypeScript, và suy ra type từ đó.
Đặt tên và cấu trúc
Đặt tên có ý nghĩa cho type gốc (User, không phải Root), export các type từ một module, và ưu tiên interface cho các cấu trúc object có thể mở rộng. Hãy định dạng và xem xét response lớn trước bằng JSON Formatter để thấy nhánh nào thực sự quan trọng.