TypeScript'te switch ifadesi, tip kontrolü eklenmiş JavaScript switch ifadesidir. Bir değeri her case ile === kullanarak karşılaştırır, eşleşen dalı çalıştırır ve break ya da return ifadesinde durur. TypeScript switch edilen değeri her case içinde daraltır ve olası her değerin ele alınıp alınmadığını kontrol edebilir.
Alt alta yazılmış label'lar (case "sat": case "sun":) tek bir dalı paylaşır. return fonksiyonu bitirir, bu yüzden ondan sonra break gerekmez.
Sözdizimi
switch (expression) {
case value1:
// runs when expression === value1
break;
case value2:
case value3:
// runs for value2 or value3
break;
default:
// runs when nothing else matched
}
- Eşleştirme katı eşitlik,
===, kullanır:case 1string olan"1"ile eşleşmez. break,returnya dathrowolmadan çalışma bir sonraki case'e devam eder (fallthrough).defaultisteğe bağlıdır ve herhangi bir yerde durabilir, ama genellikle en sona yazılır.- TypeScript'in asla eşleşmeyeceğini kanıtlayabildiği bir
casedeğeri TS2678 hatasıdır."a" | "b"olarak tiplenmiş bir parametre içincase "c":şunu bildirir:Type '"c"' is not comparable to type '"a" | "b"'.Böylece case label'larındaki yazım hataları yakalanır.
Her Case İçinde Daraltma
Her case içinde TypeScript hangi değerin eşleştiğini bilir ve tipi daraltır. Bu en çok bir discriminated union ile işe yarar: ortak etiket özelliği üzerinde switch yapın, her case kendi özellikleriyle eşleşen varyantı görür.
shape.radius yalnızca "circle" case'inde derlenir. Onun dışında shape bir dikdörtgen olabilir ve dikdörtgenin radius özelliği yoktur. default yoktur ve fonksiyon yine de number döndürüyor olarak tip kontrolünden geçer, çünkü TypeScript üç case'in her kind değerini kapsadığını görür. Bunun üzerine kurulu diğer desenler discriminated unions sayfasındadır.
never ile Exhaustive Switch
Yukarıdaki fonksiyon, case'i olmadan dördüncü bir şekil eklenirse derlenmez (TS2366, eksik bir return). Bu yalnızca fonksiyon bir değer döndürdüğünde işe yarar. void kodda da çalışan ve daha anlaşılır bir mesaj veren bir garanti için, değeri never tipine atayan bir default ekleyin:
index.ts(14,19): error TS2322: Type '{ kind: "triangle"; base: number; height: number; }' is not assignable to type 'never'.
Ele alınan case'lerden sonra shape için kalan tek tip üçgen varyantıdır ve never tipine atanamaz. Hata tam olarak neyin eksik olduğunu adlandırır. case "triangle": return (shape.base * shape.height) / 2; ekleyin; default artık never görür, blok derlenir ve 9 yazdırır. throw ise çalışma zamanında hatalı veriye karşı korumaya devam eder, örneğin tiplerin öngörmediği ve JSON'dan gelen bir kind değerine karşı.
Birçok kod tabanı bu kontrolü bir yardımcı fonksiyona sarar:
Aynı teknik enum'lar için de çalışır: enum değeri üzerinde switch yapın ve default içinde onu assertNever fonksiyonuna geçirin.
Aralıklar ve Koşullar için switch (true)
switch değerleri karşılaştırır, bu yüzden aralıklar için bir hile gerekir: true üzerinde switch yapın ve her case içine bir koşul yazın. TypeScript 5.3'ten beri bu koşullar tipleri tıpkı if ifadeleri gibi daraltır.
Case'ler sırayla test edilir, bu yüzden en özel olanı önce yazın. Bunun if / else if yapısından daha okunaklı olup olmadığı bir zevk meselesidir; davranış aynıdır.
Fallthrough ve break
Kodu olup break, return ya da throw içermeyen bir case bir sonraki case'e düşer. Bu neredeyse her zaman bir hatadır. noFallthroughCasesInSwitch derleyici seçeneği (strict kapsamında değildir) bunu TS7029 hatasına, Fallthrough case in switch., dönüştürür ve alt alta yazılmış boş label'lara yine izin verir.
Bunun gibi bilinçli bir fallthrough çalışır, ama noFallthroughCasesInSwitch açıkken yeniden yazılması gerekir, örneğin ayrı if kontrolleriyle. Bu zaten genellikle daha anlaşılırdır.
Case İçindeki Değişkenler
switch gövdesinin tamamı tek bir bloktur, bu yüzden bir case'te bildirilen bir const diğerlerinde de görünür (ve yeniden bildirmek hatadır). Bir case'e kendi kapsamını vermek için onu süslü parantezlerle sarın:
Süslü parantezler olmadan ikinci const unit bir derleme hatasıdır, TS2451: Cannot redeclare block-scoped variable 'unit'.
switch ve Nesne ile Arama
Her case yalnızca bir değeri başka bir değere eşliyorsa, Record ile tiplenmiş bir nesne daha kısadır ve TypeScript her anahtarın var olduğunu kontrol eder:
Bir anahtarı atlamak derleme hatasıdır; bu da bir never kontrolüyle aynı exhaustive garantiyi verir. switch ifadesini farklı mantık çalıştıran, union varyantlarını daraltan ya da erken dönen durumlar için saklayın.
Sıkça Sorulan Sorular
TypeScript'te switch ifadesi nasıl yazılır?
Tam olarak JavaScript'teki gibi: switch (value) { case "a": ...; break; default: ... }. Case'ler === ile karşılaştırılır. TypeScript kontroller ekler: switch edilen tiple asla eşleşemeyecek bir case değeri hatadır (TS2678) ve her case içinde switch edilen değişken o case'e daraltılır.
TypeScript'te bir switch'i nasıl exhaustive yaparım?
Değeri never tipinde bir değişkene atayan bir default ekleyin: default: { const unreachable: never = value; throw new Error(...) }. Union'ın her üyesi ele alındığında değer orada never olur ve kod derlenir. Biri eksik olduğunda derleyici eksik üyeyi bildirir (TS2322).
TypeScript switch'inde aynı kodu çalıştıran birden fazla case'i nasıl ele alırım?
Label'ları aralarında kod olmadan alt alta yazın: case "sat": case "sun": return "weekend";. Boş case'ler bir sonrakine düşer. noFallthroughCasesInSwitch seçeneği yalnızca kodu olup break ya da return içermeyen case'leri bildirir, bu yüzden alt alta yazılmış label'lara izin verilmeye devam eder.
switch (true) TypeScript'te tipleri daraltır mı?
Evet, TypeScript 5.3'ten beri. switch (true) { case typeof x === "string": ... } içinde x o case'te, bir if içinde olacağı gibi, string tipine daraltılır. Aralık ya da tip kontrolleri içeren bir if/else if zincirine okunaklı bir alternatiftir.