TYPESCRİPT STRİCT MODE: TSCONFİG AYARLARIYLA HATA YAKALAMAYI ERKENLEŞTİRMEK
Üretimde patlayan hataların büyük kısmı, kod yazılırken aslında “görünmez” olan küçük tip belirsizliklerinden doğar. TypeScript’in strict mode yaklaşımı, bu belirsizlikleri daha erken aşamada görünür kılarak hatayı “çalışma zamanı”ndan “derleme zamanı”na taşır.
Bu yazıda strict mode’un neyi değiştirdiğini, hangi tsconfig seçeneklerinin en çok fark yarattığını ve bir projeyi strict’e geçirirken nasıl kademeli ilerleyebileceğinizi pratik örneklerle ele alacağız. Hedefimiz, hata yakalamayı erkene çekmek kadar, ekip içinde sürdürülebilir bir TypeScript tip güvenliği standardı kurmak.
İster yeni bir kod tabanı başlatıyor olun ister yıllanmış bir projeyi iyileştirmek isteyin, doğru strict ayarlarıyla daha güvenli refactor, daha temiz API sözleşmeleri ve daha öngörülebilir davranışlar elde edebilirsiniz.
Primary Keyword: TypeScript strict mode neden kritik?
Primary keyword olarak “TypeScript strict mode”u düşünebiliriz: Çünkü strict, tek bir ayar gibi görünse de aslında bir dizi kontrolü devreye sokarak tip sistemini “varsayılan gevşeklikten” çıkarır. Bu sayede, “ben zaten TypeScript yazıyorum” demek yerine “TypeScript’ten gerçekten faydalanıyorum” noktasına geçersiniz.
Strict modu açmak, özellikle büyük ekiplerde ve uzun ömürlü projelerde, kodun niyetini daha net ifade eder. Bu netlik, LSI/semantic tarafta sık geçen şu hedefleri destekler: derleme zamanı hataları, refactor güvenliği, null/undefined yönetimi, implicit any riskinin azaltılması, fonksiyon sözleşmelerinin sıkılaştırılması.
Strict paketi neleri kapsar?
strict bayrağı, altında birden fazla denetimi toplar (ör. strictNullChecks, noImplicitAny, strictFunctionTypes gibi). Her biri farklı bir risk alanını hedefler: null kaynaklı çökmeler, tip kaçakları, yanlış parametre varyansları ve daha fazlası.
Strict’i açınca proje “kırılır” mı?
Mevcut kod tabanı strict’e hazır değilse, derleyici çok sayıda uyarı üretir. Bu “kırılma” değil; aksine, daha önce görünmeyen risklerin görünür hâle gelmesidir. Doğru strateji, strict’i bir gecede zorlamak yerine kademeli bir geçiş planı oluşturmaktır.

tsconfig’te strict’i etkinleştirme ve temel iskelet
Başlangıç için en net adım, tsconfig.json içinde compilerOptions.strict değerini true yapmak. Ancak gerçek değer, strict altında hangi alt kontrolleri kullanacağınızı bilmekten gelir. Modern projelerde çoğu ekip, strict’i açıp yalnızca “geçişte zorlayan” bir iki seçeneği geçici olarak yumuşatır.
Minimal ama etkili tsconfig örneği
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "Bundler",
"strict": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"skipLibCheck": true
}
}
Burada skipLibCheck genellikle üçüncü parti tip paketlerindeki gürültüyü azaltır. Bu bir “kaçış” değil, odak yönetimidir: Önce kendi kodunuzdaki tip kaçaklarını kontrol altına alın.
Geçiş planı: strict + seçici gevşetmeler
Eğer proje çok büyükse, kısa vadede strict açık kalıp bir iki alt seçenek kapatılabilir. Örneğin strictPropertyInitialization veya noUncheckedIndexedAccess gibi kontrolleri sonraya bırakmak, ekibin yükünü dengeler. Buradaki amaç “sonsuz erteleme” değil; ölçülebilir bir yol haritası oluşturmak.
strictNullChecks ile null/undefined riskini yönetmek
Birçok üretim hatasının kök nedeni, null/undefined varsayımlarının yanlış kurulmasıdır. strictNullChecks, “var olabilir” ile “kesin var” ayrımını netleştirir. Bu, API tüketiminde ve UI katmanında özellikle belirgindir.
Null daraltma (narrowing) örneği
type User = { id: string; email?: string | null };
function sendWelcome(user: User) {
if (!user.email) {
// email yoksa burada güvenli şekilde çık
return;
}
// Burada email artık string kabul edilir
console.log(user.email.toLowerCase());
}
Bu yaklaşım, “opsiyonel alan” ve “nullable alan” ayrımını bilinçli kullanmanızı sağlar. Ayrıca, domain modelinizin gerçekten neye izin verdiğini belgeleyen bir sözleşme hâline gelir.
Non-null assertion (!) ne zaman kullanılmalı?
! operatörü hızlı bir kaçış sunar ama yanlış kullanılırsa strict’in faydasını boşa çıkarır. Bu yüzden non-null assertion yerine, mümkünse guard fonksiyonları, erken return ve tip daraltma tercih edilmelidir. Gerektiğinde ise kullanım alanı, yorumla veya isimlendirmeyle açıkça gerekçelendirilmelidir.
noImplicitAny ve tip kaçaklarını kapatma
noImplicitAny, parametre ve dönüş değerlerinde “bilinmeyen” tiplerin sessizce any olmasını engeller. Bu ayar, özellikle hızlı prototipleme döneminde biriken belirsizlikleri yakalamada etkilidir.
Implicit any yerine daha doğru tipler
Aşağıdaki gibi bir fonksiyon, strict dışı bir konfigürasyonda kolayca any sızıntısı yaratabilir. Strict ile birlikte, doğru tipleri tanımlamaya yönelirsiniz:
function groupById(items: Array<{ id: string }>) {
const map: Record<string, { id: string }> = {};
for (const item of items) {
map[item.id] = item;
}
return map;
}
Burada küçük gibi görünen tip tercihleri, ileride refactor sırasında büyük fark yaratır. Özellikle “derleme zamanı hataları” ile “sonradan keşfedilen runtime bug” ayrımında, noImplicitAny güçlü bir kaldıraçtır.
strictFunctionTypes, varyans ve callback güvenliği
Fonksiyon tipleri, özellikle event handler’lar, callback’ler ve middleware katmanlarında sıkça kullanılır. strictFunctionTypes, fonksiyon parametreleriyle ilgili daha güvenli bir kontrol sağlayarak “aslında uyumsuz” callback’lerin geçmesini engeller.
Callback sözleşmesini netleştirme
Örneğin bir API katmanında “başarı/başarısızlık” callback’leri tanımlıyorsanız, parametre tiplerini bilinçli tasarlamak zorundasınız. Bu da hatalı parametre kullanımını daha derlemede yakalar. Sonuç olarak, callback cehennemi değil; daha öngörülebilir bir kontrol akışı elde edersiniz.
strictPropertyInitialization ile sınıf alanlarını güvenceye almak
Class tabanlı kodlarda (özellikle framework veya SDK geliştiriminde), alanların constructor içinde başlatılması kritik. strictPropertyInitialization, “undefined bırakılmış alanlar”ı erkenden yakalar. Bu ayar, görünürde zahmetli olsa da üretimde belirsiz state problemlerini ciddi biçimde azaltır.
Başlatma stratejileri
- Constructor içinde zorunlu alanları kesin olarak set etmek
- Opsiyonel alanları gerçekten opsiyonel yapmak ve kullanımda guard eklemek
- Gerekli durumlarda “factory function” ile nesne oluşturmayı standardize etmek
Burada amaç, sınıfın yaşam döngüsünü daha okunur hâle getirmek ve refactor güvenliği kazanmak.
noUncheckedIndexedAccess ile dizi/obje erişimlerini daha güvenli yapmak
Bir diziden indeksle eleman çektiğinizde veya bir objeye dinamik key ile eriştiğinizde, aslında sonuç “yok” olabilir. noUncheckedIndexedAccess, bu gerçeği tipe yansıtır. Bu sayede, sınır durumlar daha erken ele alınır.
Dinamik erişimlerde guard yaklaşımı
Bu ayar açıldığında, arr[0] gibi erişimler bile T | undefined dönebilir. İlk anda gürültülü görünse de özellikle kullanıcı girdisi, API yanıtı ve config okumalarında ciddi dayanıklılık sağlar. Proje büyükse, bu ayarı strict’e geçişin ikinci fazına almak mantıklı olabilir.

Strict’e geçiş için pratik bir kontrol listesi
Strict’e geçişi yönetilebilir kılmak için küçük bir kontrol listesi işinizi kolaylaştırır. Bu liste, ekip içi anlaşmayı ve sürdürülebilirliği güçlendirir:
- Yeni kod için strict’i zorunlu kılın, eski kod için kademeli hedef belirleyin
- Önce strictNullChecks ve noImplicitAny ile en kritik riskleri kapatın
- Hata sayılarını ölçün, haftalık/iki haftalık azaltım hedefleri koyun
- Tip daraltma ve guard pattern’lerini dokümante edin
- CI’de typecheck’i ayrı bir adım olarak koşturun
Bu süreçte ekip içi ortak bir dil oluşturmak için kapsamlı bir öğrenme yolu da faydalı olur: TypeScript Eğitimi içeriğinde strict ayarlarını gerçek projeler üzerinden pekiştirebilirsiniz.
“Her şeyi strict yapalım” tuzağından kaçınma
Strict bir hedef ama aynı zamanda bir süreçtir. Bazı legacy alanlarda kısa vadede pragmatik çözümler gerekebilir. Buradaki kritik nokta, geçici çözümleri görünür kılmak ve zamanla kaldırılacak şekilde planlamaktır.
Sonuç: Daha erken hata yakalama, daha güvenli refactor
Doğru yapılandırılmış bir tsconfig strict ayarları seti, yalnızca hataları azaltmaz; aynı zamanda kodun anlaşılabilirliğini ve değişime dayanıklılığını artırır. Strict mode ile TypeScript, “tip notları”ndan çıkar, gerçek bir kalite bariyerine dönüşür.


