ProgramlamaBackend geliştirici

TypeScript'te sembol (Symbol) tip mekanizması nasıl çalışır? Bir nesnenin anahtarı olarak sembol kullanmanın avantajları ve özellikleri nelerdir ve TypeScript ile API tasarlarken hangi ince noktaları dikkate almak gerekir?

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

Cevap.

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, özellik anahtarının benzersizliğini garanti eder; bu, hiçbir string anahtar için mümkün değildir.
  • Symbol anahtarları ile özellikler, normal döngülerde (for...in, Object.keys) görüntülenmez. Bu, gizli özellikler için kullanışlıdır.
  • Tüm standart işlemler (örneğin, JSON.stringify) Symbol anahtarlarını dikkate almaz — bu, serileştirme ve ters serileştirme esnasında önemlidir.

Yanıtı zorlaştıran sorular.

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

Tip hataları ve anti-patternler

  • Sembollerin doğrudan birçok yerde oluşturulması (belirsiz yeniden kullanılan Symbol(…)). Bu, farklı, eşleşmeyen anahtarlara yol açar.
  • Symbol anahtarlarıyla normal string'ler gibi çalışmak — bu, erişim hatalarına ve özellik kaybına yol açar.
  • Symbol anahtarlarının JSON.stringify ile serileştirileceği beklentisi — bu özellikler kaybolur.

Gerçek hayat örneği

Olumsuz durum

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:

  • Hızlı prototipleme.

Eksileri:

  • Gerçek özel alan yok.
  • İsim çakışması riski.
  • Sistem parçaları arasında veri sızıntısı.

Olumlu durum

İ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:

  • Güvenilir gizlilik.
  • Çakışma riski minimumdur.

Eksileri:

  • Yeni çalışanlar için belirgin olmayan bir arayüz.
  • Gizli alanları hata ayıklamak daha zordur.