ProgramlamaFrontend geliştirici

TypeScript, kullanıcı tanımlı tür koruyucuları (type guards) ile nasıl çalışır, bunlar neden gereklidir ve nasıl doğru type predicate fonksiyonları oluşturulur? Uygulamalarında karşılaşılan tipik tuzaklar nelerdir?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

Soru tarihi: TypeScript, geliştiricilerin nesnelerin belirli bir türe uyup uymadığını kontrol eden kendi kullanıcı tanımlı işlevlerini (type guards) oluşturmasına olanak tanıyarak normal tür kontrollerini genişletir. Bu, bir değer türünün farklı olabileceği birim türleri, dinamik yapılar ve API'ler ile çalışmak için gereklidir.

Sorun genellikle, typeof ve instanceof ile yapılan normal tür kontrollerinin yalnızca ilkel türler ve sınıflar ile sınırlı olmasıdır; yapılar veya karmaşık türler bununla belirlenemez. Derleyiciye güvenli bir şekilde hangi durumlarda bir değerin istenen türe daraltıldığını açıkça belirtmek gerekir.

Çözüm - return tipinde bir type predicate olan function isCat(obj: Animal): obj is Cat {...} biçiminde koruyucu işlevler yazmaktır.

Kod örneği:

interface Dog { bark: () => void; } interface Cat { meow: () => void; } type Pet = Dog | Cat; function isDog(pet: Pet): pet is Dog { return (pet as Dog).bark !== undefined; } function makeSound(pet: Pet) { if (isDog(pet)) { pet.bark(); } else { pet.meow(); } }

Anahtar özellikler:

  • Tür kontrolü, parametre tipinin is Type biçiminde özel type predicate fonksiyonları aracılığıyla gerçekleştirilir.
  • Herhangi bir yapı için kendi guards'ınızı oluşturabilir ve bunları kullanabilirsiniz, yalnızca sınıf nesneleri için değil.
  • Hatalı type guards, çalışma zamanı hatalarına ve yanlış tür daraltmalarına neden olabilir.

Zorluk içeren sorular.

Type guard fonksiyonunda true/false döndürmek yeterli midir ki derleyici türü daraltsın?

Hayır. Dönüş türünü type predicate (örneğin, pet is Dog) biçiminde açıkça belirtmek önemlidir; aksi takdirde TypeScript, değerin türünü otomatik olarak daraltmayacaktır, hatta fonksiyon sadece true veya false döndürse bile.

Type guard'ı callback içinde (örneğin, filter'da) kullanmak mümkün mü ve daraltma doğru çalışacak mı?

Evet, type guard doğru şekilde anotasyona sahipse, derleyici filter sonrasında ve forEach/callback fonksiyonlarının içinde dizi elemanlarının türünü daraltır. Ancak anotasyon yoksa veya yanlış yazılmışsa, sonuç birim (union) tür olarak kalır; belirli bir tür elde edilemez.

const pets: Pet[] = [...]; const dogs = pets.filter(isDog); // TypeScript, dogs: Dog[] olduğunu biliyor

Kullanıcı tanımlı type guard'lar, typeof ve instanceof ile yapılan normal tür kontrollerinden ne farkla ayrılır?

Type guard fonksiyonları, herhangi bir yapının kontrolünü gerçekleştirmeyi, herhangi bir karmaşıklıkta kontrolleri tanımlamayı ve sınıfsız arayüzleri işlemeyi sağlar, sadece temel türler ve sınıflarla sınırlı değildir.

Tipik hatalar ve anti-deseni

  • Type guard, type-predicate tipi döndürmüyorsa ve sadece boolean döndürüyorsa - derleyici için etkisi yoktur.
  • Yalnızca yüzeysel anahtarları kontrol eder, yapı bütünlüğünü garanti etmez.
  • Type guard her zaman true döndürür, bu da tip korumasını fiilen devre dışı bırakır.
  • Giriş parametresi çok genel, ya da doğrulama olmadan örtük tür dönüşümü yapılır.

Hayattan bir örnek

Olumsuz durum

Fonksiyon, type predicate olmadan kullanıcıları filtreler:

function isValidAdmin(user: any): boolean { return user.isAdmin === true; } const admins = users.filter(isValidAdmin); // admins: any[]

Artılar:

  • Hızlı, etki çalışma zamanında belirgindir

Eksiler:

  • Filtrelemeden sonra, TypeScript için veri tipi açıklanmaz, özelliklere erişimde hatalar olabilir.

Olumlu durum

Fonksiyon, doğru type predicate ile filtreleme yapar:

interface Admin { name: string; isAdmin: true; } function isAdmin(user: any): user is Admin { return user && user.isAdmin === true; } const admins = users.filter(isAdmin); // admins: Admin[]

Artılar:

  • Sonuçların tipi kesin olarak bilinir
  • Sonuçla ilgili daha fazla işlem yaparken hata olasılığı azalır

Eksiler:

  • İmza ve kontrol kapsamına biraz daha fazla dikkat gerektirir