Zod ilə TypeScript Runtime Validasiyası: Bugları Compile-dan Əvvəl Öldür
TypeScript sənə compile-time təhlükəsizlik verir, amma runtime-da API-dən gələn datanı kim yoxlayır? Zod ilə hər iki dünyada güvəndə ol.
Zod ilə TypeScript Runtime Validasiyası: Bugları Compile-dan Əvvəl Öldür
Salam, developer dostlar! Bu gün danışacağımız mövzu Bakıdakı hər bir TypeScript yazan developerin bilməli olduğu bir şeydir — runtime validasiya. Əgər sən "TypeScript var, mənə niyə lazımdır?" deyirsənsə, bu məqalə tam sənin üçündür.
Problem: TypeScript Sənə Yalan Danışır (Bir Növ)
Bunu etiraf edək — hamımız bunu etmişik. API-dən data gəlir, biz ona as UserResponse yazırıq və TypeScript xoşbəxt olur. Amma runtime-da həmin response-un içində name əvəzinə null gəlir, app crash edir, və sən gecə saat 2-də production bugfix edirsən.
TypeScript compile-time tipləri yoxlayır. Amma sənin API-dən, formdan, URL parametrlərindən, localStorage-dan gələn datanı heç kim yoxlamır. Bu, evin qapısına kilid vurmaq, amma pəncərəni açıq qoymaqdır.
Bakıda fintech, e-commerce layihələrdə işləyən developerlərin çoxu bunu yaşayıb. Kapital Bank-ın, Bravo-nun və ya hər hansı lokal startupun API-si ilə işləyirsənsə, backend cavabının gözlənilən formatda gəlməsinə güvənmə — yoxla.
Zod Nədir?
Zod — TypeScript-first schema validation kitabxanasıdır. 2024-cü ildən bəri npm-də həftəlik 25 milyondan çox yüklənmə ilə ən populyar validation kitabxanasına çevrilib. Joi, Yup kimi alternativlərdən fərqi — TypeScript ilə native inteqrasiya edir və sxemdən avtomatik tip çıxarır.
Qısa desək: bir dəfə schema yaz, həm runtime validation, həm TypeScript tipi əldə et.
Quraşdırma
bashnpm install zod
Bu qədər. Dependency yoxdur, yüngüldür (~50KB unpacked), və tree-shaking ilə daha da kiçilir.
Real Nümunə: İstifadəçi Qeydiyyatı
Gəl Bakıda bir startup üçün qeydiyyat forması validasiyası yazaq:
typescriptimport { z } from "zod"; // Schema təyin edirik const UserRegistrationSchema = z.object({ name: z.string().min(2, "Ad minimum 2 simvol olmalıdır"), email: z.string().email("Düzgün email daxil edin"), age: z.number().min(18, "18 yaşdan kiçiklər qeydiyyatdan keçə bilməz"), city: z.enum(["Bakı", "Gəncə", "Sumqayıt", "Lənkəran", "Digər"]), salary_expectation_azn: z.number().min(800).max(15000).optional(), phone: z.string().regex( /^\+994(50|51|55|70|77)\d{7}$/, "Azerbaycan mobil nömrəsi formatında olmalıdır" ), }); // TypeScript tipi AVTOMATIK çıxır — əl ilə yazmağa ehtiyac yoxdur! type UserRegistration = z.infer<typeof UserRegistrationSchema>; // İstifadə function registerUser(data: unknown) { const result = UserRegistrationSchema.safeParse(data); if (!result.success) { console.error("Validation xətaları:", result.error.issues); // result.error.issues hər bir xətanı detallı göstərir return { success: false, errors: result.error.flatten() }; } // Burada result.data artıq tam tiplidir! // TypeScript bilir ki, result.data.city "Bakı" | "Gəncə" | ... dir console.log(`${result.data.name} qeydiyyatdan keçdi, şəhər: ${result.data.city}`); return { success: true, user: result.data }; }
Burada safeParse metoduna diqqət et — error throw etmir, nəticəni success boolean ilə qaytarır. Production kodda bu pattern daha təhlükəsizdir.
API Response Validasiyası
Bakıdakı layihələrdə tez-tez rast gəlinən ssenari — backend komandası response strukturunu xəbərsiz dəyişir. Zod bunu tutur:
typescriptconst ProductResponseSchema = z.object({ id: z.number(), title: z.string(), price_azn: z.number().positive(), in_stock: z.boolean(), images: z.array(z.string().url()).min(1), created_at: z.string().datetime(), }); type Product = z.infer<typeof ProductResponseSchema>; async function fetchProducts(): Promise<Product[]> { const response = await fetch("/api/products"); const json = await response.json(); const result = z.array(ProductResponseSchema).safeParse(json); if (!result.success) { // Sentry-yə və ya lokal monitorinq sisteminə göndər console.error("API response formatı dəyişib!", result.error); throw new Error("Gözlənilməz API response"); } return result.data; }
Bu pattern ilə backend dəyişiklik edəndə, sən dərhal bilirsən — production-da deyil, development-da.
Zod + React Hook Form
Əgər Next.js və ya React ilə işləyirsənsə, @hookform/resolvers paketi ilə Zod-u form validasiyasına birbaşa bağlaya bilərsən:
typescriptimport { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; const form = useForm<UserRegistration>({ resolver: zodResolver(UserRegistrationSchema), });
Bir schema, həm backend, həm frontend validasiyası. DRY prinsipi əslində belədir.
Niyə İndi?
Bakıda developer bazarında TypeScript bilən mütəxəssislərə tələbat artıb. LinkedIn-də Azərbaycan üzrə TypeScript pozisiyalarının 60%-dən çoxu Zod və ya oxşar runtime validation tələb edir. ABB, PASHA Holding, Kapital Bank kimi şirkətlərin texniki müsahibələrində "API response-u necə validasiya edərdin?" sualı tez-tez verilir. as casting əvəzinə Zod istifadə etmək — senior-junior fərqini göstərən detallardandır.
Maaş kontekstində desək, Bakıda TypeScript + Zod + Next.js stack-i bilən middle developer 1800-3500 AZN arası maaş gözləyə bilər, amma bu stack-siz olan React developer hələ 1200-1800 AZN diapazonunda qalır.
Zod vs Alternativlər
| Kitabxana | TypeScript-first | Bundle Size | Həftəlik Yüklənmə |
|---|---|---|---|
| Zod | ✅ Bəli | ~50KB | ~25M |
| Yup | ❌ Sonradan | ~75KB | ~12M |
| Joi | ❌ Xeyr | ~140KB | ~10M |
| Valibot | ✅ Bəli | ~5KB | ~1.5M |
Valibot daha yüngüldür, amma ekosistemi hələ Zod qədər yetkin deyil. 2026-da standart seçim hələ də Zod-dur.
Praktiki Məsləhətlər
.parse()əvəzinə.safeParse()istifadə et — production-da error throw etmək əvəzinə, graceful error handling et- Schema-ları ayrı fayllara yaz —
schemas/user.ts,schemas/product.tskimi strukturla .transform()ilə datanı çevir — məsələn, stringdən gələn qiymətinumber-ə parse et.refine()ilə custom validasiya yaz — FIN kodu, VÖEN yoxlaması kimi Azərbaycana xas qaydalar üçün
typescriptconst FinCodeSchema = z.string().refine( (val) => /^[A-Z0-9]{7}$/.test(val), { message: "FIN kodu 7 simvoldan ibarət olmalıdır" } );
Nəticə
TypeScript sənə compile-time-da kömək edir, amma real dünyada data gözlənilməzdir. Zod bu boşluğu doldurur — bir schema ilə həm tip təhlükəsizliyi, həm runtime validasiya əldə edirsən. Əgər hələ as casting ilə yaşayırsansa, bu gün Zod-a keç. Sənin gecə saat 2-dəki production bugfix-lərinin sayı azalacaq.
Gələn həftə tRPC + Zod ilə end-to-end type safety mövzusunu yazacam. Stay tuned!
Sualın var? Kommentdə yaz, ya da Telegram qrupumuza qoşul.
Oxşar məqalələr
Zod ilə TypeScript Runtime Validasiyası: Bugları Production-da Deyil, Əvvəlcədən Tut
TypeScript compile-time-da tip yoxlayır, amma runtime-da API-dən gələn datanı kim yoxlayacaq? Zod ilə validasiyanı necə həll edəcəyini real nümunələrlə göstərirəm.
TypeScript ilə Supabase inteqrasiyası — tam tip təhlükəsizliyi
Supabase + TypeScript birlikdə işlədəndə runtime xətaları minimuma enir. Database-dən gələn hər sətir tipli olur. Necə? Bu məqalədə.
TypeScript Generics — Nədir, Niyə Lazımdır, Necə İstifadə Olunur?
TypeScript generics-i başa düşmək Bakıda frontend və backend vakansiyaların 70%-ində tələb olunan skilldir. Bu bələdçi ilə generics-i bir dəfəlik öyrən.