Sekilas, TypeScript dan Zod terlihat seperti menyelesaikan masalah yang sama. Padahal, keduanya bekerja pada lapisan yang berbeda dan justru saling melengkapi. Pada bab ini kita akan membahas perbedaannya agar peran masing-masing menjadi lebih jelas.
TypeScript memeriksa tipe data pada saat kita menulis kode. Setelah dikompilasi menjadi JavaScript, semua anotasi tipe akan dihapus. Pada saat aplikasi berjalan di browser atau server, yang tersisa hanyalah JavaScript murni.
Mari perhatikan contoh berikut:
Sekilas terlihat aman, bukan? Function getUser dianotasikan dengan return type Promise<User>. Akan tetapi, sebenarnya tidak ada yang memeriksa apakah data benar-benar sebuah User. TypeScript hanya mempercayai anotasi tersebut. Apabila API tiba-tiba mengembalikan { name: 'Nauval', age: 'dua belas' }, kode kita akan tetap berjalan dan baru gagal di tempat lain ketika data tersebut digunakan.
Sebagai contoh, kita ingin menampilkan umur pengguna pada tahun depan:
Tidak ada error yang dilempar. Akan tetapi, hasilnya sudah jelas salah, karena JavaScript melakukan string concatenation alih-alih operasi penjumlahan. Atau, kasus lain, ketika kita melakukan pengecekan:
Pengguna yang seharusnya boleh mengakses fitur tersebut, justru ditolak. Lagi-lagi tanpa error yang jelas. Bug seperti ini termasuk yang paling sulit dilacak, karena gejalanya muncul jauh dari sumber masalahnya.
Zod memeriksa tipe data pada saat kode berjalan. Kita menulis schema, lalu mem-parse data yang masuk. Apabila data tersebut tidak sesuai, Zod akan langsung melempar error pada saat itu juga.
Sekarang, apabila API mengembalikan data yang tidak valid, kita akan mendapatkan error yang jelas, di tempat yang jelas, dengan informasi yang detail.
Zod tidak menggantikan TypeScript. Keduanya saling melengkapi:
Selain itu, kita dapat menurunkan tipe TypeScript langsung dari schema Zod melalui z.infer, sehingga tidak ada duplikasi:
Schema dan tipe selalu sinkron, karena keduanya berasal dari satu sumber. Apabila kita menambahkan field baru pada userSchema, tipe User akan ikut diperbarui secara otomatis.
Aturan praktisnya adalah setiap kali data berasal dari luar kendali kita, lakukan validasi menggunakan Zod. Beberapa contohnya:
JSON.parse dari localStorageUntuk data internal yang sepenuhnya kita kendalikan, cukup gunakan TypeScript saja. Validasi menggunakan Zod tidak diperlukan, karena TypeScript sudah memadai pada konteks tersebut.
Tipe Theme di atas hanya memiliki dua kemungkinan nilai, dan keduanya dideklarasikan di dalam kode kita sendiri. TypeScript sudah cukup untuk memastikan parameter current selalu salah satu dari 'dark' atau 'light', tanpa perlu validasi tambahan.

Jadilah yang pertama untuk berdiskusi!