TypeScript satisfies — Cái 'công tắc' mà hồi đó mình ước có
Chào mấy bạn,
Mấy bữa nay mình đang refactor lại cái codebase TypeScript cũ ở công ty, tự dưng nhớ lại hồi xưa cứ phải loay hoay với cái type annotation trong TS. Có một thằng mình muốn giới thiệu với mấy bạn hôm nay — cái satisfies operator. Nghe tên hơi lạ, nhưng dùng hoài luôn.
Ảnh: Lukas Blazek — Pexels
Tại sao mình cần nó?
Giả sử bạn có một object config kiểu:
const config = {
api: 'https://api.example.com',
timeout: 5000,
retry: true,
} satisfies Record<string, string | number | boolean>;
Hồi xưa nếu dùng Record thì mất hết type cụ thể của từng property. Còn satisfies vừa kiểm tra đúng shape, vừa giữ nguyên type chính xác — config.api là string, config.timeout là number. Hai bên đều vui.
Hay có một ví dụ khác mà mình gặp hoài:
type Color = 'red' | 'green' | 'blue';
type ColorMap = Record<string, Color>;
const palette = {
primary: 'red',
secondary: 'green',
warning: 'blue',
} satisfies ColorMap;
Đây là cái hay: vừa được inference chi tiết cho từng key, vừa không bỏ sót lỗi kiểu dữ liệu. Cú pháp nhẹ nhàng, nhưng hiệu quả bất ngờ.
Ảnh: Sarah — Pexels
Khi nào nên xài?
Mình thấy satisfies hợp nhất khi bạn muốn:
- Kiểm tra một object với một type tổng quát, nhưng vẫn cần autocomplete cho từng field
- Đảm bảo object đúng interface nào đó (VD:
ZodSchema,AxiosConfig) mà không muốn đánh mất type chi tiết - Kết hợp với Record, Map, hay generic type
Nói chung, nếu mấy bạn đang xài TypeScript 4.9+ và chưa thử satisfies thì hãy dành 5 phút chơi thử. Mình cá là các bạn sẽ thích à.
Chúc mọi người code vui vẻ! ✨