JavaScript'te Spread operatörü (...), nesneleri kopyalamak ve genişletmek için kolaylık sağlamak amacıyla ortaya çıktı, dizilerle uzun zamandır kullanılıyor, ES2018 itibarıyla nesnelerle de kullanılmaya başlandı. TypeScript'te Spread, sadece bir sözdizimsel iyileştirme değil, nesnelerle işlem yaparken dikkatli türlendirme için bir araç haline geldi.
Tarihsel olarak, JavaScript'te bir nesnenin klonlanması veya genişletilmesi Object.assign aracılığıyla yapılırdı, ancak bu yaklaşım kolayca tür güvenliğinin kaybolmasına ve karmaşık nesne yapılarında anahtarların tehlikeli bir şekilde kesişmesine yol açabiliyordu.
Sorun, Spread kullanarak nesnelerin birleştirilmesi/genişletilmesi durumunda TypeScript'in yeni bir tür çıkarmasıdır, bu girdi yapılarından olası anahtar çakışmalarını işleyerek ("son gelen kazanır") ama bu her zaman geliştiricinin amaçladığı şey değildir. Özel alanların, optional alanların, readonly ve sınıflardaki özel özelliklerin kesişimlerine dikkat edilmelidir.
Çözüm: Spread kullanmak ve TypeScript derleyicisinin sonucu otomatik olarak türetmesine izin vermek. Karmaşık durumlar için girdi yapı türünü açıkça sınırlamak ve tür değişikliklerini dikkatle izlemek önemlidir.
Kod örneği:
interface User { name: string; age: number; } interface Extra { isAdmin?: boolean; readonly city: string; } const base: User = { name: 'Ivan', age: 28 }; const extended: User & Extra = { ...base, city: 'Moscow', isAdmin: true };
Anahtar özellikler:
TypeScript'te Spread kalıtımı ile bir nesnenin "derin kopyasını" almak mümkün mü?
Cevap: Hayır. Spread sadece yüzeysel kopyalamayı (shallow copy) gerçekleştirir, iç içe nesneler referansla kalır.
const original = { user: { name: 'Anna' } }; const cloned = { ...original }; cloned.user.name = 'Maria'; // original.user.name da değişecektir
Spread ile çakışan anahtarları olan nesnelerde tür daralacak mı yoksa genişleyecek mi ve bu değişkenin anotasyonunu nasıl etkiler?
Cevap: Spread sırasında değişkenin türü genişler ve anahtarların çakışması durumunda sağdaki özellikler kazanır; eğer açık bir tür anotasyonu varsa, türler uyumsuzsa hata meydana gelebilir.
const a = { id: 4, value: "abc" }; const b = { value: 123 }; const c: { id: number; value: number } = { ...a, ...b }; // tamam
Spread sınıflara uygulanabilir mi ve özel özelliklerle ne olur?
Cevap: Spread sadece sınıfın kamu özelliklerine uygulanabilir. Özel (private/#) ve korumalı protected alanlar sonuç nesnesine dahil edilmez.
class Person { private id = 77; name = "Bob"; } const p = new Person(); const spreaded = { ...p }; // spreaded: { name: string }
Geliştirici, kullanıcı seçeneklerini genişletmek için settings nesnesinin değerlerini Spread yapar:
const common = { theme: 'light', notifications: true }; const user = { notifications: false, signature: 'Sasha' }; const merged = { ...common, ...user };
merged değişkeninin türle uyumlu olmasını bekler ama yanlışlıkla signature alanının türüyle ilgili hata yapar, Spread'in sadece anahtarları kopyaladığını ve değerlerini doğrulamadığını unutur.
Artılar:
Eksiler:
Aşağıdaki gibi bir doğrulama ve dönüş türü anotasyonu ile Spread sadece yapılandırmaları birleştirmek için kullanılır:
interface Settings { theme: "light" | "dark"; notifications: boolean; signature?: string; } function getSettings(common: Settings, specific: Partial<Settings>): Settings { return { ...common, ...specific }; }
Artılar:
Eksiler: