ProgramlamaFullstack Geliştirici

TypeScript'te keyof operatörü nasıl çalışır, ne için kullanılır ve güvenli fonksiyonlar ve API tasarımını nasıl etkiler?

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

Cevap.

Soru Tarihi

TypeScript, nesnelerin katı tiplenmesi ve JavaScript'te daha öngörülebilir bir kod yazma amacıyla başından beri geliştirilmiştir. Nesnelerin özelliklerine erişimde güvenliği sağlamak için kullanılan araçlardan biri olan keyof operatörü, TypeScript 2.1 ile birlikte ortaya çıkmıştır. Bu operatör, belirli bir nesne tipinde mevcut olan dize (ve sembol) anahtarlarının bir kümesini temsil eden türler oluşturmayı sağlar.

Sorun

Saf JavaScript'te, nesne özellikleri herhangi bir dize ile sorgulanabilir ve bir hata yapılırsa sonuç undefined veya çalışma sırasında yalnızca bulunan bir hata ortaya çıkar. Katı tiplenme olmadan, yazım hatası yapma veya yeniden yapılandırma sırasında anahtar dizesinin güncellenmesini unutmak kolaydır. Ayrıca, belirli bir nesne veya tür için yalnızca geçerli anahtarları alan bir fonksiyon oluşturmak sıkça gereklidir.

Çözüm

keyof operatörü, türün tüm anahtarlarından bir union-tipi oluşturur. Bununla birlikte, kabul edilen anahtarları sınırlamak, API güvenliğini artırmak (örneğin, getter/setter işlevleri için) ve genel yardımcı türler oluşturmak mümkündür.

Kod örneği:

type User = { name: string; age: number; active: boolean }; type UserKey = keyof User; // "name" | "age" | "active" function getProp<T, K extends keyof T>(obj: T, key: K): T[K] { return obj[key]; } const user: User = { name: 'Tom', age: 33, active: true }; const age = getProp(user, 'age'); // yaş number türünde

Ana özellikler:

  • Nesnenin yapısına bağlı olan "anahtar" türleri ilan etmeye olanak tanır.
  • Get/set özellik fonksiyonlarını maksimum derecede tip güvenli hale getirir — yazım hataları ve mevcut olmayan anahtarlar hariç tutulur.
  • TypeScript 2.7 ve sonrası ile sembolik özellikler (symbol) ile birlikte çalışır.

Kandırmacalı Sorular.

Dizi için keyof ne döndürür ve indeksleri alabilir miyiz?

Diziler için keyof, dizinin gerçekte JS'de bir nesne olduğu anahtar türlerini döndürür. Genellikle, bu dizi indeksleri ve dizinin özel özellikleridir.

Kod örneği:

type A = keyof number[]; // "length" | "toString" | "pop" | ... | number

keyof, union-tipylerin anahtarlarını döndürebilir mi?

Evet, union-tipi için keyof, her iki nesnenin anahtarlarının kesişimini döndürür, birleşimini değil.

Kod örneği:

type A = {a: string, b: number } type B = {b: number, c: boolean } type C = keyof (A | B); // "b"

Eğer bir nesnenin özelliği opsiyonel ise ne olur? keyof "?" destekliyor mu?

Evet, opsiyonel özellikler de sonuç anahtar türüne dahil edilir, ancak bu, özelliğin çalışma zamanında nesnede mutlaka mevcut olduğu anlamına gelmez.

Kod örneği:

type D = { a: string; b?: number }; type DK = keyof D; // "a" | "b"

Tür Hataları ve Anti-Desenler

  • Anahtarlar için keyof yerine sabit dize kullanmak — tür kaybı.
  • Union için keyof'un birleşimi döndürdüğünü düşünmek, kesişimi değil.
  • keyof'un yalnızca açıkça ilan edilmiş anahtarları değil, miras alınanları da hesaba katacağını ummak.

Gerçek Hayattan Bir Örnek

Negatif Durum

Bir getProperty(obj, key) fonksiyonu yazıyorlar, anahtar dize tipi ile çağırıyorlar — mevcut olmayan bir anahtar ile çağrıldığında hata yalnızca çalışma sırasında ortaya çıkıyor.

Artılar:

  • Genel kod.

Eksiler:

  • Derleme aşamasında kontrol yok, yeniden yapılandırma sırasında hatalar, yazım hatalarına karşı boşluk.

Pozitif Durum

Generic kullanıyorlar: getProperty<T, K extends keyof T>(), anahtar tipi yapıların anahtarları ile katı şekilde sınırlıdır.

Artılar:

  • Kesin tür güvenliği, yazım hatası veya anahtardaki hatalar mümkün değil.

Eksiler:

  • Kod biraz daha karmaşık, generikler her zaman yeni başlayanlar için anlaşılır değildir.