Konunun geçmişi:
Symbol tipi, JavaScript'te (ES6) benzersiz tanımlayıcılar oluşturmak için eklendi; bu tanımlayıcılar diğer nesne özellikleriyle asla çakışmayacaktır. TypeScript, ES6 uyumluluğu eklendiğinden bu yana sembolleri desteklemektedir.
Sorun:
Symbol'dan önce, nesne özellikleri için anahtar olarak genellikle string'ler kullanılıyordu. Bu, nesneleri genişletme veya yeniden kullanma esnasında hatalara yol açıyordu: rastgele isim çakışmaları ve özel özellikleri gizleme imkânsız hale geliyordu (hatta konvansiyon yoluyla bile). Symbol, dış kod tarafından görünmeyen, benzersiz anahtarlar oluşturma olanağı sağladı, ancak tip bildirimi ile ilgili sorular gündeme geldi — Symbol anahtarları ile nasıl tip tanımlanır ve bunlar API'de güvenli bir şekilde nasıl kullanılır?
Çözüm:
TypeScript, sembolleri değerler ve tipler olarak desteklemektedir; ancak Symbol anahtarlarının tiplendirilmesi belirli özelliklere sahiptir. Bir sembol oluşturmak için global yapıcı veya global sembol kaydını kullanabilirsiniz. Arayüzlerde veya tiplerde sembollerle anahtarlar açıkça symbol tipi olarak belirtilmelidir ve bu tür özelliklere erişim yalnızca Symbol'a kaydedilen referansla sağlanır.
Kod örneği:
const SECRET = Symbol('secret'); interface SecretObject { [SECRET]: string; visible: string; } const obj: SecretObject = { visible: 'beni gör', [SECRET]: 'gizli', }; console.log(obj.visible); // 'beni gör' // console.log(obj["secret"]); // Hata: böyle bir özellik yok! console.log(obj[SECRET]); // 'gizli'
Anahtar özellikler:
Symbol, nesnelerde kullanıldığında otomatik olarak bir string'e dönüştürülebilir mi?
Hayır, Symbol otomatik olarak string'e dönüştürülemez; bunu yapmaya çalışmak (örneğin, birleştirerek) hata ile sonuçlanır.
const mySymbol = Symbol('desc'); // alert('prefix_' + mySymbol); // TypeError
Symbol anahtarları Object.keys üzerinden sıralanabilir mi?
Hayır, Object.keys ve for...in Symbol anahtarlarını göz ardı eder. Bu anahtarları elde etmek için Object.getOwnPropertySymbols kullanılmalıdır.
const sym = Symbol('a'); const obj = { [sym]: 42 }; Object.keys(obj); // [] Object.getOwnPropertySymbols(obj); // [Symbol(a)]
Symbol anahtarlarına sahip özellikler Object.assign ile kopyalandığında iletilir mi?
Evet, Object.assign hem string hem de sembol anahtarlarını kopyalar; bu, JSON.stringify'den farklıdır.
const s = Symbol('s'); const o1 = { [s]: 123, foo: 'bar' }; const o2 = Object.assign({}, o1); o2[s]; // 123
Bir geliştirici, özel özellikler için string anahtarlar ('_private') kullanarak konvansiyona güvendi. Team B yanlışlıkla aynı dizeyi ekledi — özellikler çakıştı ve beklenmedik bir hata oluştu.
Artı yönler:
Eksileri:
İkinci geliştirici, gizli özellikler için Symbol kullandı (örneğin, Symbol('internal')). Artık takım içinde bile iç verileri yanlışlıkla çakıştıramazsınız: erişim yalnızca belirli bir Symbol'a referansla mümkündür.
Artı yönler:
Eksileri: