Menu

TypeScript Dictionary: Index Signature, Record ve Map

TypeScript'te ayrı bir dictionary ya da hashmap class'ı yoktur; anahtar-değer eşlemesini index signature, Record<K, V> ya da Map<K, V> ile tiplersiniz. Her birini, bir anahtarın var olup olmadığını kontrol etmeyi, ekleme, silme ve döngüyü ve noUncheckedIndexedAccess seçeneğinin dictionary'ler için neden önemli olduğunu öğrenin.

Bu sayfada çalıştırılabilir editörler var - düzenle, çalıştır ve sonucu anında gör.

TypeScript'te ayrı bir dictionary ya da hashmap class'ı yoktur. Bir dictionary ya index signature ile tiplenmiş düz bir nesnedir, { [key: string]: number }, ya aynı tipin Record<string, number> yazımıdır ya da bir Map<string, number>'dır. Üçü de değerleri anahtara göre saklar; anahtar tiplerinde, eksik anahtarların nasıl tiplendiğinde ve nasıl serileştirildiklerinde ayrışırlar.

String anahtarlar ve JSON biçimli veri için Record<string, T> ile tiplenmiş bir nesne olağan seçimdir. String olmayan anahtarlar ya da sürekli eklenip silinen girdiler için Map kullanın.

Index Signature

Bir index signature, [key: KeyType]: ValueType, "bu tipteki her anahtar bu tipte bir değere karşılık gelir" der. Anahtarın adı (key, name, userId) yalnızca belgeleme içindir. Anahtar tipi string, number, symbol, template literal kalıpları ya da bunların union'ı olabilir.

JavaScript number anahtarları string'e çevirir; bu yüzden bir { [id: number]: string } nesnesinin anahtarları çalışma zamanında yine string'dir: Object.keys({ 1: "one" }) sonucu [ '1' ] olur. Number index signature yalnızca TypeScript'te nesneye nasıl erişebileceğinizi kısıtlar.

Record<K, V>

Record<string, V>, { [key: string]: V } için bir kısaltmadır. string yerine literal anahtarlardan oluşan bir union verildiğinde, her anahtarı içermek zorunda olan sabit bir dictionary'ye dönüşür:

urls içinden staging anahtarını çıkarmak TS2741 derleme hatasıdır (Property 'staging' is missing...); bu da union anahtarlı Record'u denetlenen bir arama tablosu yapar. Partial her değeri number | undefined yapar.

Hash Map Olarak Map

Bir Map her tipte anahtarı kabul eder, ekleme sırasını korur, bir size değerine sahiptir ve eksik anahtarları dürüstçe tipler: get, V | undefined döndürür.

Bir Anahtarın Var Olup Olmadığını Kontrol Etmek

Birkaç kontrol yolu vardır ve hepsi aynı anlama gelmez:

KontrolNerede çalışırDikkat edilecek nokta
Object.hasOwn(obj, key)nesnelerES2022; eski hedeflerde Object.prototype.hasOwnProperty.call(obj, key) kullanın
key in objnesnelertoString ve constructor gibi miras alınan anahtarlar için de true
obj[key] !== undefinednesnelerEksik bir anahtarı undefined olarak saklanmış bir anahtardan ayıramaz
if (obj[key])nesneler0, "" ve false değerleri için de false
map.has(key)MapSonraki bir map.get(key) çağrısını daraltmaz
map.get(key) !== undefinedMapNesnelerdeki undefined uyarısının aynısı

Miras alınan anahtar sorunu, kullanıcıdan gelen "constructor" ya da "__proto__" gibi anahtarların düz nesneleri dictionary olarak riskli yapmasının nedenidir. Bir Map böyle anahtarlara sahip değildir.

Eksik Anahtarın Tip Sorunu

Bir index signature ya da Record<string, T> üzerinde herhangi bir anahtarı okumanın tipi T'dir, var olmayan bir anahtar için bile. Derleyici, çalışma zamanında undefined olan bir değer üzerinde metot çağırmanıza izin verir:

noUncheckedIndexedAccess derleyici seçeneği bunu düzeltir: bu seçenekle colors["grass"] ifadesinin tipi string | undefined olur ve siz kontrol edene kadar toUpperCase çağrısı bir derleme hatasıdır. strict kapsamında değildir, bu yüzden tsconfig.json içinde ayrıca açılması gerekir; yanında duran diğer bayraklar için strict mode sayfasına bakın. Bir Map'te böyle bir boşluk yoktur, çünkü get her zaman undefined içerir.

Ekleme, Silme ve Döngü

delete, index signature özelliklerinde çalışır. Bir nesne tipinin zorunlu adlandırılmış bir özelliğinde ise TS2790 derleme hatasıdır: The operand of a 'delete' operator must be optional.

Hangisini Kullanmalı

İhtiyaçKullanın
String anahtarlar, JSON girdi ya da çıktıRecord<string, T>
Sabit, bilinen ve hepsi zorunlu bir anahtar kümesiRecord<"a" | "b", T>
Adlandırılmış özellikler artı rastgele ek anahtarlarindex signature içeren bir nesne tipi
Nesne olan anahtarlar, number olarak kalması gereken sayılar ya da string olmayan her şeyMap<K, V>
Sık ekleme ve silme ya da sık okunan bir boyutMap<K, V>
Kullanıcıdan gelen anahtarlarMap<K, V> (miras alınan anahtar yok)

Sıkça Sorulan Sorular

TypeScript'te nasıl dictionary oluştururum?

Düz bir nesneyi index signature ile tipleyin, const ages: { [name: string]: number } = {}, ya da eşdeğeri olan Record<string, number> ile. Sonra girdileri ages["ada"] = 36 ile ekleyin. String olmayan anahtarlar ya da sık sık ekleme ve silme yapılan bir koleksiyon için new Map<string, number>() kullanın.

TypeScript'te HashMap var mı?

Bu adla yok. JavaScript'in yerleşik Map class'ı bir hash map'tir: Map<K, V> anahtar-değer çiftlerini anahtarla hızlı erişim için saklar, ekleme sırasını korur ve her anahtar tipini kabul eder. String anahtarlar için diğer yaygın seçenek Record<string, V> olarak tiplenmiş düz bir nesnedir.

TypeScript dictionary'sinde bir anahtarın var olup olmadığını nasıl kontrol ederim?

Nesne dictionary'si için Object.hasOwn(dict, key) ya da key in dict kullanın (ikincisi toString gibi miras alınan özellikleri de görür) veya değeri okuyup undefined ile karşılaştırın. Bir Map için map.has(key) kullanın ya da map.get(key) sonucunu doğrudan kontrol edin, çünkü has sonraki bir get çağrısını daraltmaz.

Index signature ile Record arasındaki fark nedir?

{ [key: string]: T } ve Record<string, T> aynı tipi tanımlar. Record daha kısadır ve belirli anahtarlardan oluşan bir union da alabilir, Record<"a" | "b", T>, bu durumda her anahtar zorunludur. Index signature ise tek bir nesne tipinde adlandırılmış özelliklerle birleştirilebilir ve anahtarı onu belgeleyen bir ad taşıyabilir, örneğin { [userId: string]: User }.

Eksik bir dictionary anahtarını okumak neden hata vermiyor?

Varsayılan olarak bir index signature ya da Record<string, T> üzerinde dict[key] ifadesinin tipi T'dir, oysa eksik bir anahtar için değer çalışma zamanında undefined olur. tsconfig.json içinde noUncheckedIndexedAccess seçeneğini açarsanız tip T | undefined olur ve kontrol yapmanız zorunlu hale gelir. strict bu seçeneği içermez.

Coddy programming languages illustration

Coddy ile kodlamayı öğren

BAŞLA