Şimdi dürüst olayım: TypeScript’i gerçekten öğrendiğini sanıp da sonra bir projede patlayan insan sayısı az değil. Ben de yıllar önce, 2022’nin sonlarında İstanbul’da bir ekip toplantısından çıkıp masama oturduğumda tam böyle hissediyordum. Kod kopyala-yapıştırla dönüyor, ama “neden böyle yazdık?” sorusuna cevap veremiyordum. İşte bu yüzden, hazır bir kütüphaneye sarılmadan küçük bir form doğrulayıcı yazma fikri bana bayağı mantıklı geldi.
Bak şimdi, Bu yaklaşımın güzelliği şu: büyük sistemi anlamaya çalışırken boğulmuyorsun. Minik bir şey yapıyorsun. Kullanıcı adı, e-posta, şifre… hepsi tanıdık alanlar. Ama işin içine tip güvenliği girince, olay bildiğiniz mutfakta çorba taşmasına dönüyor — küçük detaylar bile çok şeyi değiştiriyor.
Neden Böyle Bir Şeye Girişilir?
Kendi deneyimimden konuşuyorum, Bir geliştirici için “öğrenme” ile “ezber” arasındaki çizgi çoğu zaman bulanık oluyor. Ben bunu 2023’te Ankara’daki bir freelance işte net gördüm: ekip TypeScript kullanıyordu. Bazı arkadaşlar sadece örnek kodları alıp ilerliyordu. O sırada biri bana “abi şu generic meselesini açıklar mısın?” diye sordu ve ben cevap verirken takıldım. İşin aslı şu ki, abstractions üstünden konuşmak kolay; gerçek problem çözmeye gelince konu dağılıyor.
Çok konuştum, örnekle göstereyim.
İşte burada sıfırdan yazılan minik araçlar devreye giriyor. Çünkü library kurup iki satır kullanınca rahat ediyorsun — ama ne yaptığını pek kavramıyorsun. Küçük bir validator yazınca ise schema — en azından ben öyle düşünüyorum — nedir, veri nasıl akıyor, hangi alan zorunlu kalıyor, hata mesajı nasıl toplanıyor (inanın bana). bu sorular tek tek önüne geliyor (kendi tecrübem). Siz hiç denediniz mi? Kaçış yok.
Açıkçası, Ha bu arada, bu yaklaşım yalnızca yeni başlayanlara iyi gelmiyor. Kurumsal tarafta da işe yarıyor. Ekip içi standartları anlamak için bazen dışarıdan gelen dev paketlerden önce basit örnekler görmek gerekiyor. E peki, sonuç ne oldu? Büyük sistemlerde bile en sağlıklı öğrenme yöntemi bazen oyuncak gibi görünen küçük araçlardan geçiyor — bence bu biraz garip ama böyle.
Evet, doğru duydunuz.
Koddan Çok Mantığı Anlamak Lazım
Fikir aslında basit. Bir schema veriyorsun, yanında da data seti geliyor; validator da sana “şu alan eksik”, “bu e-posta saçma”, “şifren kısa” diyor. Kağıt üstünde düz görünse de pratikte birkaç katman var — tipler, runtime kontrolü ve hata toplama işi aynı anda yürüyor. Biraz jimnastik gibi yani.
Bana göre TypeScript’in öğretici tarafı tam burada başlıyor. Çünkü sadece syntax ezberlemiyorsun; veri sözleşmesi düşünüyorsun. Yani email alanı string mi olacak? Zorunlu mu? Pattern kontrolü ister mi? Minimum uzunluk kaç karakter? Bu sorular kulağa sıradan geliyor. Gerçek projede seni kurtaran şey bunlar oluyor.
Şimdi gelelim işin can alıcı noktasına.
Schema ile veri neden ayrı tutuluyor?
Şahsen, Ayrı tutuluyor çünkü schema kuralları anlatıyor, data ise o kurallara uymaya çalışan ham malzeme oluyor. Tıpkı tarif defteriyle mutfaktaki malzemeyi ayırmak gibi. Tarif bozuksa ortaya kötü yemek çıkar; veri bozuksa uygulama kullanıcıyı yanlış yönlendirir.
Ben bunu geçen ay İzmir’de yaptığım bir yan projede birebir yaşadım. Form alanlarını doğrudan component içine gömmüşbüyük çoğunluk ve sonra validasyon kuralları üç yerde tekrar etmeye başladı — evet, klasik hata, utanılacak türden. Schema’ya geçince hem kod kısaldı hem de bakım yükü ciddi biçimde azaldı. Gerçekten ciddi.
Tiny ama faydalı yapı nasıl görünüyor?
type FieldRule = {
required?: boolean;
pattern?: RegExp;
minLength?: number;
};
type Schema<T> = {
[K in keyof T]: FieldRule;
};
function validate<T extends Record<string, any>>(schema: Schema<T>, data: T) {
const errors: Partial<Record<keyof T, string[]>> = {};
for (const key in schema) {
const rules = schema[key];
const value = data[key];
if (rules.required && !value) {
errors[key] ||= [];
errors[key].push("This field is required");
continue;
}
if (typeof value === "string" && rules.minLength && value.length < rules.minLength) {
errors[key] ||= [];
errors[key].push(`Minimum length is ${rules.minLength}`);
}
if (typeof value === "string" && rules.pattern && !rules.pattern.test(value)) {
errors[key] ||= [];
errors[key].push("Invalid format");
}
}
return { valid: Object.keys(errors).length === 0, errors };
}
type FieldRule = {
required?: boolean;
pattern?: RegExp;
minLength?: number;
};
type Schema<T> = {
[K in keyof T]: FieldRule;
};
function validate<T extends Record<string, any>>(schema: Schema<T>, data: T) {
const errors: Partial<Record<keyof T, string[]>> = {};
for (const key in schema) {
const rules = schema[key];
const value = data[key];
if (rules.required && !value) {
errors[key] ||= [];
errors[key].push("This field is required");
continue;
}
if (typeof value === "string" && rules.minLength && value.length < rules.minLength) {
errors[key] ||= [];
errors[key].push(`Minimum length is ${rules.minLength}`);
}
if (typeof value === "string" && rules.pattern && !rules.pattern.test(value)) {
errors[key] ||= [];
errors[key].push("Invalid format");
}
}
return { valid: Object.keys(errors).length === 0, errors };
}Evet, çok karmaşık değil. Zaten mesele de o değil mi? İnsan bazen devasa soyutlamalara dalınca ana fikri kaçırıyor. Buradaki yapı biraz lego gibi çalışıyor: parça parça ekliyorsun ve sonunda oynanabilir hale geliyor. Sade ama iş görüyor.
Kopyala-Yapıştır Konforu Neden Yetmiyor?
Açık konuşayım: hazır paket kullanmak çoğu zaman doğru karar. Kimse her şeyi sıfırdan yazsın demiyor zaten! Ama sürekli aynı çözümleri taklit edince beynin kas hafızası gelişmiyor. Elin alışıyor belki, kafa tembel kalıyor.
Ben editör masasında bu konuyu ilk gördüğümde hemen not aldım çünkü çok tanıdık geldi — Temmuz 2024’te Kadıköy’deki ofiste yeni başlayan stajyerlere TypeScript anlatırken biri “generic’ler ne işe yarıyor?” diye sormuştu ve sınıfta adeta sessizlik çökmüştü, garip bir andı gerçekten. Sonra ufak örneklerle ilerleyince herkesin yüzü açıldı (buna dikkat edin). Hep böyle olur işte.
| Yaklaşım | Artısı | Eksiği |
|---|---|---|
| Hazır kütüphane | Hızlı başlatma | Mantığı saklayabiliyor |
| Sıfırdan mini araç | Kavrama kolaylığı | Bazıları için yavaş ilerler |
| Karma yaklaşım | Denge sağlar | Tasarımı iyi düşünmek gerekir |
Neyse uzatmayalım. Hazır çözümün kötü olduğu yok tabi ki, ama öğrenme aşamasında bazen fazla rahat ettiriyor —. Bu rahatlık insana zarar verebiliyor, her şeyi olmaması gereken şekilde kolaylaştırıyor.
Peki Bu Mini Validator Ne Öğretiyor?
Bence en önemli ders şu: type safety sadece derleme zamanı oyunu değil. TypeScript sana güzel ipuçları verir, yine de kullanıcı tarayıcıda saçma veri girebilir. O yüzden ikisi beraber yürümeli. Runtime’ı unutunca iş patlıyor.
Bu aracı kurcalarken benim kafamda netleşen başka bir konu da generics oldu (yanlış duymadınız). Önceden generic deyince gözümde devasa akademik bir şey canlanıyordu — nasıl desem, üniversite derslerindeki o ağır soyutlamalar gibi. Sonra baktım ki mesele oldukça günlük: fonksiyona verdiğin nesnenin şeklini korumak istiyorsun, hepsi bu. Mesela validate<SignupForm> dediğinde sistem sana “tamam, ben bu formu biliyorum” diyor (ben de ilk duyduğumda şaşırmıştım). Fena değil yani; hatta baya işe yarayan türden bir soyutlama.
Bir dakika, şunu da ekleyeyim: böyle küçük projeler seni framework bağımlılığından biraz uzaklaştırıyor. Hangi paketi niye kullandığını daha iyi sorgulamaya başlıyorsun. Geçen yıl Eylül ayında Bursa’da tanıştığım backend geliştiricisi Serhat da aynısını söylemişti; “Kendi ufak aracını yazmadan üçüncü parti pakete güvenmem artık” demişti — haksız değildi bence. 128 GB DDR5 RAM Neden Uçtu: Raflarda Kalan Fatura yazımızda bu konuya da değinmiştik. Daha fazla bilgi için Eski JavaScript’i Bırakın: Modern API’ler İş Görüyor yazımıza bakabilirsiniz.
Küçük startup ile enterprise arasında fark var mı?
Var tabii. Küçük startup’ta hız ön planda olur; (söylemesi ayıp) iki kişiyseniz ve ürününüzün MVP’si varsa, böyle hafif çözümler müthiş rahatlık sağlar. Enterprise seviyede ise iş biraz farklı: loglama, i18n hata mesajları, erişilebilirlik uyumu, test kapsamı ve bakım maliyeti öne çıkar — yani orada minicik validator yetmez, çevresine sağlam bir disiplin kurulması gerekir. Bu konuyla ilgili Artemis II’nin Dönüşü: Ay Çevresinden Eve Gelen Yolculuk yazımıza da göz atmanızı tavsiye ederim.
Gel gelelim öğrenme tarafında ikisinin ortak noktası aynı: sahiden anlayarak ilerlemek. Kod tabanınız ister beş bin satır olsun ister beş yüz bin, elinizle tuttuğunuz küçük parçalar size büyük resmi öğretiyor (şaşırtıcı ama gerçek)
En iyi öğretmen bazen dokümantasyon değil… ellerin kirlenmesi oluyor.
Bunu özellikle ilk kez kendi validator’ımı yazarken anladım.
Kod kırılıyor mu? Evet.
Ama tam orada öğrenme başlıyor!
Npm’e Yayınlamak Neden Önemliydi?
Bir proje yapıp kenara atmakla npm’e koymak arasında ciddi fark var. Paket olarak yayınlayınca isim seçimiyle uğraşıyorsun, README hazırlıyorsun, sürüm numarası düşünüyorsun… yani iş oyuncağın dışına çıkıyor. Birdenbire gerçek hissettiriyor.
Kısacası, kendi deneyimimden konuşuyorum, Ben bunu hep seviyorum çünkü insan ürünü gerçek dünyaya çıkarınca kusurlarını daha net görüyor. Mesela form-validator-ts adı güzel duruyor olabilir ama dokümantasyon zayıfsa paket kimsenin umurunda olmaz. Kaba gerçeği söyleyeyim: teknik kalite tek başına yetmiyor. Anlatabilmek de gerekiyor. Chunking Neden RAG’in En Büyük Hatası Olabiliyor? yazımızda da bu konuya değinmiştik. Text Clustering: Yemek Başlıklarından Anlam Çıkarmak yazımızda da bu konuya değinmiştik.
Bu nokta bana biraz AI PR’leri hatırlatıyor. Kod hızlı üretilir belki, ama insan gözüyle bakılmadığında bariz hatalar kalabiliyor. Aynısı mini kütüphaneler için de geçerli: paket çalışsa bile API sezgisel değilse insanlar bırakıp gidiyor. Maalesef.
Kullanıcıya Ne Kazandırır?
- Daha temiz formlar sunar.
- Tiplerle runtime kontrolleri aynı çizgide tutar.
- Ekip içinde standart yaratmayı kolaylaştırır.
- Eğitim amacıyla TypeScript’i somutlaştırır.
- Kütüphane bağımlılığını azaltabilir ya da geciktirebilir.
Eh, Buradaki kazançların bazıları teknikten çok kültüre dair aslında. Takımların çoğu kodu paylaşırken stil rehberi konuşur ama veri doğrulama konusu çabuk unutulur. Oysa giriş ekranlarından ödeme formlarına kadar her yerde aynı dert döner: yanlış input, eksik alan, gereksiz karmaşa. Mantıklı değil mi? Kısacası standardizasyon bedava değil; emek ister, ama geri dönüşü iyi.
Beklediğim kadar değildi dediğim yer neresi?
Şurası açık: yalnızca birkaç rule ile yapılan validator uzun vadede sınırlı kalabiliyor. Bilhassa nested object’ler, array validation veya async kontroller gerektiğinde iş büyür — o noktada kendi aracınızı genişletmeniz gerekir ya da köklü bir çözüme dönmeniz. Yani evet, başlangıç için harika… üretim ölçeğinde ise biraz ham kalabiliyor. Dürüst olmak gerekirse.
Pratik ipucu ne?
Şöyle ki, Ben olsam ilk versiyonda sadece required / pattern / minLength ile başlar, sonra ihtiyaç geldikçe genişletirdim. Hemen on özellik eklemek yerine tek akışı düzgün yapmak daha mantıklı — tencereye tüm baharatları boşaltmak yerine tadına bakarak gitmek gibi düşünün.
Sence En Büyük Ders Ne?
En büyük ders şu oldu: “öğrenmek” pasif dinlemekle olmuyor. Eli klavyeye götürmeden oturmuyor hiçbir şey. İki saatlik kafa karışıklığı bazen iki haftalık videodan daha faydalı (ilk duyduğumda inanamadım). Bunu küçümsemiyorum; aksine bizzat savunuyorum — çünkü pratik çatlakları gösteriyor. Kitapta görmediğiniz detayı ancak hata alınca fark ediyorsunuz.
Bunu yaşayan biri olarak söyleyeyim, Az önce X dedim. Aslında — hayır dur, daha doğrusu Y daha doğru olabilir: mesele sadece TypeScript’i öğrenmek değil, kendine sorun çözme refleksi kazandırmak. Bugün form doğrulayıcı olur; yarın event bus olur; ertesi gün belki custom hook ya da build tool ayarı… zincir oradan büyüyor.
Araya gireyim: Bakın şimdi, şöyle bağlayayım: eğer siz de TS’e yeni geçtiyseniz, devasa framework oyunlarına girmeden minicik, biteviye olmayan, hatta biraz toy duran işler yapın. Hem eğlenirsiniz hem canınız sıkılır — ve garip biçimde en çok o anlarda öğrenirsiniz.
Sıkça Sorulan Sorular
TypeScript form doğrulayıcı sıfırdan yazılır mı?Evet, yazılır ve öğrenme açısından çok faydalıdır. Basit kurallarla başlayıp required, pattern ve minimum uzunluk gibi kontroller ekleyebilirsiniz. Ama üretim ortamında kapsam büyüdükçe mevcut kütüphaneleri değerlendirmek daha mantıklı olabilir.
<>
<
”
Eğer amacınız öğrenmekse kendi çözümünüz çok daha öğreticidir. Hangi parçanın ne yaptığını birebir görürsünüz ve generic mantığını daha hızlı kavrarsınız. Sadece hız gerekiyorsa hazır paket genelde daha pratiktir.
/>
Hayır, şart değil. Ama yayınlamak sizi README,sürümleme ve API tasarımı konusunda ciddiye zorlar. Yani ekstra emek var; karşılığında gerçek dünya tecrübesi kazanırsınız.
<>
Tek başına yeterli olmayabilir. Küçük uygulamalarda iş görür,kurumsalda ise nested yapı,async validation,lokalizasyon ve test stratejileri gerekir. Yani temel olarak güzel,ama üzerine mimari koymanız şart.
<>
Kaynaklar ve İleri Okuma〈/h2〉
TypeScript Resmi Dokümantasyonu
Bu içerik işinize yaradı mı?
Benzer içerikleri kaçırmamak için beni sosyal medyada takip edin.



