Salvo

WFN Üye
Konular
1,743
Mesajlar
1,765
Çözüm
0
Ticaret Puanı
0
Üyelik
6 Ay 16 Gün
Konum
İstanbul
Web Sitesi
Yok
Alanı
Belirtmemiş
1/1
Konu sahibi
İlk bakışta Object.keys() kullanmak yeterli görünür; ancak TypeScript bu işlevin sonucunu genel olarak string[] olarak verir. Anahtarları nesnenin gerçek anahtar türleriyle güvenli biçimde dolaşmak için ya anahtarı keyof typeof nesne olarak daraltmalı ya da bunu yapan küçük bir yardımcı işlev kullanmalısınız. Böylece nes[key] erişimi güvenli kalır ve anahtarın değer türü doğru biçimde korunur.

() neden doğrudan yeterli değildir?​


Aşağıdaki örnekte Object.keys(settings) sonucu çalışma zamanında anahtar adlarını içerir; fakat TypeScript bu dizinin elemanlarını yalnızca string kabul eder:

Kod:
const settings = {
  theme: "dark",
  pageSize: 20,
};

for (const key of Object.keys(settings)) {
  // key: string
  // settings[key] doğrudan güvenli kabul edilmez.
}

Bunun nedeni TypeScript’in çalışma zamanında nesnenin gerçekten yalnızca bildirilmiş anahtarlara sahip olduğunu varsaymamasıdır. JavaScript nesnesi sonradan değiştirilebilir veya dışarıdan beklenmeyen bir anahtar alabilir. Bu nedenle Object.keys() dönüşünün otomatik olarak (keyof typeof settings)[] sayılmaması bilinçli bir güvenlik tercihidir.

Bilinen bir nesnede güvenli dolaşım​


Nesneyi kod içinde siz oluşturduysanız ve anahtarların türünü biliyorsanız, anahtarları keyof typeof settings türüne dönüştürerek değer erişimini güvenli hâle getirebilirsiniz:

Kod:
const settings = {
  theme: "dark",
  pageSize: 20,
} as const;

type SettingKey = keyof typeof settings;

for (const key of Object.keys(settings) as SettingKey[]) {
  const value = settings[key];

  console.log(key, value);
}

Bu örnekte key yalnızca "theme" | "pageSize" olabilir. Buna bağlı olarak settings[key] ifadesi de "dark" | 20 türünde değerlendirilir. as const kullanılmazsa anahtar türleri yine doğru biçimde çıkarılır; ancak değerler string ve number gibi daha genel türlere genişletilebilir.

Bu tür dönüşüm, nesnenin yalnızca kendi bildiğiniz anahtarları içerdiğinden emin olduğunuz durumlarda uygundur. Nesne dışarıdan geliyorsa veya çalışma zamanında ek özellik alabiliyorsa, dönüşümü sorgusuz kullanmak gerçekte olmayan bir anahtarı güvenliymiş gibi gösterebilir.

Tekrar kullanılabilir güvenli anahtar yardımcı işlevi​


Aynı yaklaşımı her döngüde yeniden yazmak yerine, anahtarları nesnenin anahtar türüyle döndüren bir yardımcı işlev tanımlayabilirsiniz:

Kod:
function typedKeys<T extends object>(object: T): Array<keyof T> {
  return Object.keys(object) as Array<keyof T>;
}

const user = {
  id: 42,
  name: "Ayşe",
  active: true,
};

for (const key of typedKeys(user)) {
  const value = user[key];

  console.log(`${String(key)}:`, value);
}

Burada typedKeys(user) sonucu ("id" | "name" | "active")[] olarak görülür. user[key] erişimi de nesnenin tanımlı özelliklerinden biriyle sınırlanır.

Ancak yardımcı işlev çalışma zamanında Object.keys() davranışını değiştirmez; yalnızca TypeScript’e dönen anahtarların keyof T ile uyumlu olduğunu bildirir. Bu nedenle bu işlevi, nesnenin gerçek anahtarlarının TypeScript türüyle uyumlu olduğu kontrollü kodlarda kullanın. Güvenilmeyen JSON verisini önce doğrulamadan bu türü kesin gerçek gibi kabul etmeyin.

Anahtar ve değeri birlikte dolaşmak​


Anahtarın yanında değere de ihtiyacınız varsa Object.entries() kullanabilirsiniz. Bu işlevde de TypeScript çoğu durumda anahtarları genel string, değerleri ise genel bir tür olarak görür. Bilinen bir nesnede girişleri türlendirmek için küçük bir yardımcı işlev kullanılabilir:

Kod:
function typedEntries<T extends object>(object: T): Array<[keyof T, T[keyof T]]> {
  return Object.entries(object) as Array<[keyof T, T[keyof T]]>;
}

const prices = {
  book: 120,
  pen: 25,
};

for (const [key, value] of typedEntries(prices)) {
  console.log(key, value);
}

Bu örnekte key "book" | "pen", value ise number türündedir. Fakat bu genel imzada belirli bir anahtar ile onun kendine özgü değer türü arasındaki ilişki her zaman korunmaz. Örneğin farklı anahtarların farklı değer türleri varsa, value tüm olası değer türlerinin birleşimi olarak görülebilir.

Bu nedenle seçim, ihtiyaca göre yapılmalıdır:
İhtiyaçUygun yaklaşımDikkat edilmesi gereken
Yalnız anahtarları dolaşmak() ve keyof türüTür dönüşümü nesnenin çalışma zamanı yapısıyla uyumlu olmalıdır.
Anahtar ve değeri birlikte almak() ve türlendirilmiş yardımcı işlevAnahtar-değer ilişkisi her zaman ayrı ayrı korunmayabilir.
Güvenilmeyen dış veriÖnce şema veya çalışma zamanı doğrulamasıTypeScript türü tek başına gelen veriyi doğrulamaz.

Belirli bir anahtara göre işlem yaparken daraltma​


Her anahtarın farklı bir değer türü varsa, yalnızca genel bir keyof döngüsü bazen yeterli olmaz. TypeScript, bir birleşim türündeki anahtar ile değerin hangi çifte ait olduğunu her zaman otomatik olarak ilişkilendiremez. Böyle bir durumda anahtarları açıkça kontrol ederek değeri daraltabilirsiniz:

Kod:
const product = {
  name: "Kalem",
  stock: 15,
  available: true,
};

for (const key of typedKeys(product)) {
  const value = product[key];

  if (key === "name") {
    console.log(value.toUpperCase());
  } else if (key === "stock") {
    console.log(value.toFixed(0));
  } else {
    console.log(value ? "Satışta" : "Tükendi");
  }
}

Bu örnekte her koşul, ilgili anahtarın beklenen değer işlemiyle eşleştirilir. Rastgele bir anahtar adı oluşturup nesneye erişmek yerine anahtarları keyof ile sınırlamak, yazım hatalarını derleme aşamasında yakalamaya yardımcı olur.

Güvenli kullanım için kısa karar kuralı​


Nesne kod içinde sabit ve kontrollü biçimde oluşturuluyorsa Object.keys(object) as Array<keyof typeof object> veya typedKeys() kullanılabilir. Anahtarlarla birlikte değerleri almanız gerekiyorsa typedEntries() benzeri bir yardımcı işlev tercih edin. Nesne API, dosya veya kullanıcı girdisi gibi dış bir kaynaktan geliyorsa önce çalışma zamanında doğrulayın; keyof yalnızca derleyiciye bilgi verir, gelen verinin gerçekten bu yapıya sahip olduğunu kanıtlamaz.

Döngü sonunda TypeScript hata veriyorsa önce nesnenin türünü ve anahtar dizisinin gerçekten keyof ile sınırlandırılıp sınırlandırılmadığını kontrol edin. Hata yalnızca anahtar-değer ilişkisinin korunmamasından kaynaklanıyorsa, değeri ilgili anahtar üzerindeki koşuldan sonra kullanın veya nesneyi anahtar-değer ilişkisini taşıyan bir birleşim türüyle modelleyin.
 

Sende şimdi bize katılmak ister misin?

Kayıt ol

Bize katılım kolay ve ücretsizdir!

Foruma git ?

Bu konuyu görüntüleyen kullanıcılar

Bu konuyu şu anda görüntüleyen üye bulunmuyor.
Robotlar:
  • Anthropic