TypeScript 6.0 Yayınlandı: 7.0’a Geçiş Köprüsü
TypeScript ekibi, dilin 6.0 sürümünü yayınladı. Bu sürüm, mevcut JavaScript tabanlı derleyici kod tabanı üzerine kurulu son büyük sürüm olarak konumlandırılıyor. 6.0, TypeScript 5.9 ile Go diline taşınmış olan 7.0 arasında bir köprü görevi görüyor ve büyük ölçüde 7.0’a geçişi kolaylaştıracak uyum çalışmalarını içeriyor.
Yeni sürüme npm üzerinden ulaşılabiliyor:
npm install -D typescript
6.0 neden bir “köprü sürüm”?
TypeScript ekibi geçen yıl derleyici ve dil servisinin Go dilinde yeniden yazıldığını duyurmuştu. Yeni kod tabanı, yerel kod hızı ve paylaşılan bellek üzerinde çok iş parçacıklı çalışma avantajlarından yararlanmayı hedefliyor; TypeScript 7.0’ın temelini de bu kod tabanı oluşturacak. 6.0’daki değişikliklerin büyük çoğunluğu, kullanıcıların 7.0 davranışına hazırlanmasına yardımcı olmak için eklenmiş.
Ekip, 7.0’ın tamamlanmaya oldukça yaklaştığını belirtiyor. Yerel önizleme, Visual Studio Code eklentisi ve @typescript/native-preview paketi üzerinden test edilebiliyor. 6.0’ı benimseyebilen ekiplerin, 7.0 yerel önizlemelerini de denemesi teşvik ediliyor.
Beta ve RC’den bu yana değişenler
Beta sürümünden bu yana birkaç dikkate değer ayar yapılmış; bu ayarlar çoğunlukla 7.0 davranışıyla hizalanmayı amaçlıyor:
- Generic çağrılardaki fonksiyon ifadeleri için tip denetimi, özellikle generic JSX ifadelerinde sıkılaştırıldı. Bu değişiklik mevcut kodda daha fazla hata yakalayabilir; bazı generic çağrılar açık tip argümanı gerektirebilir.
import... assert {...}sözdizimi için başlatılan kullanımdan kaldırma uyarısı, artıkimport(..., { assert: {...} })biçimindeki dinamikimport()çağrılarını da kapsıyor.- DOM tipleri güncel web standartlarını yansıtacak şekilde tazelendi; Temporal API’lerine ilişkin bazı düzenlemeler de bu güncellemenin parçası.
this kullanmayan fonksiyonlarda bağlam duyarlılığının azaltılması
TypeScript, açık tipi olmayan parametreleri beklenen türden ya da aynı çağrının başka argümanlarından çıkarımla türetebilir. Aşağıdaki örnek arrow fonksiyonlarıyla sorunsuz çalışır:
declare function callIt<T>(obj: {
produce: (x: number) => T,
consume: (y: T) => void,
}): void;
callIt({
consume: y => y.toFixed(),
produce: (x: number) => x * 2,
});
Aynı kod metot söz dizimiyle yazıldığında ise, özellik sırasına bağlı olarak y parametresi unknown olarak çıkabilir:
callIt({
consume(y) { return y.toFixed(); },
// ~
// error: 'y' is of type 'unknown'.
produce(x: number) { return x * 2; },
});
Bunun nedeni şu: TypeScript, generic çıkarım sırasında “bağlama duyarlı fonksiyonları” (parametreleri açık tipe sahip olmayan fonksiyonlar) atlayıp diğer argümanlardan çıkarım yapmaya çalışır. Metot söz diziminde örtük bir this parametresi bulunur, arrow fonksiyonlarında bulunmaz. Örtük this, çevreleyen nesnenin tipiyle ilgili bir çıkarım gerektirebilir; bu da fonksiyonu bağlam duyarlı yapar.
TypeScript 6.0, fonksiyon içinde this‘in gerçekten kullanılıp kullanılmadığına bakıyor. Kullanılmıyorsa fonksiyon bağlam duyarlı sayılmıyor ve çıkarım sırasında öncelik kazanıyor. Böylece yukarıdaki metot söz dizimli örnek de sorunsuz çalışıyor. Bu iyileştirme, Mateusz Burzyński’nin katkısıyla eklendi.
#/ ile başlayan subpath import desteği
Node.js’in modül desteğine eklediği subpath imports özelliği, paketlerin kendi içindeki modüllere iç takma adlar tanımlamasına olanak tanıyor. Örneğin:
{
"name": "my-package",
"type": "module",
"imports": {
"#root/*": "./dist/*"
}
}
Böylece ../../utils.js gibi göreli yollar yerine #root/utils.js yazılabiliyor. Ancak # karakterinden sonra her zaman bir segment yazma zorunluluğu, bundler kullanıcılarının alışkın olduğu @/ gibi kısa öneklerin karşılığını üretmeyi zorlaştırıyordu. #/ ile başlayan yollar önceden desteklenmiyordu.
Node.js yakın zamanda #/ ile başlayan subpath import’ları desteklemeye başladı; bu destek yeni Node.js 20 sürümleriyle geliyor. TypeScript 6.0 da bu kullanımı --moduleResolution ayarının nodenext ve bundler değerleri altında destekliyor:
{
"name": "my-package",
"type": "module",
"imports": {
"#/*": "./dist/*"
}
}
Bu katkı magic-akari tarafından sağlandı.
--moduleResolution bundler ile --module commonjs birlikte kullanılabiliyor
Önceden --moduleResolution bundler, yalnızca --module esnext veya --module preserve ile birlikte kullanılabiliyordu. --moduleResolution node (yani node10) kullanımdan kaldırıldığı için, birçok proje için en uygun yükseltme yolunun bu yeni kombinasyon olduğu belirtiliyor.
Proje türüne göre alternatif hedefler de var: paketlenmiş bir web uygulaması için --module preserve ve --moduleResolution bundler; Bun ya da Node.js uygulaması için ise --module nodenext yönünde bir geçiş planı öneriliyor.
--stableTypeOrdering bayrağı
TypeScript, karşılaştığı tiplere sıra numarası olarak iç tip ID’leri atar ve union türlerini bu ID’lere göre tutarlı biçimde sıralar. Aynı işlem özellikler için de geçerli. Sonuç olarak bildirim sırası, üretilen bildirim (declaration) dosyalarındaki union sırasını değiştirebilir. Örneğin:
// some-file.ts
export function foo(condition: boolean) {
return condition ? 100 : 500;
}
// some-file.d.ts
export declare function foo(condition: boolean): 100 | 500;
Üstüne alakasız bir const x = 500; eklenirse bildirim çıktısı 500 | 100 hâline dönüşür, çünkü 500 önce işlenmiş olur.
TypeScript 7.0’ın öne çıkan mimari değişikliklerinden biri paralel tip denetimi. Bu paralelizm, farklı denetleyicilerin düğüm, tip ve sembolleri farklı sıralarla ziyaret etmesi anlamına geliyor; bu da iç ID atamalarını deterministik olmaktan çıkarabilir. Sonuç: aynı programda içerikleri özdeş iki dosya farklı bildirim çıktıları veya farklı hata sonuçları üretebilir.
Bu sorunu çözmek için TypeScript 7.0, iç nesneleri (tipler ve semboller gibi) içeriklerine dayalı deterministik bir algoritmaya göre sıralıyor. Böylece yukarıdaki örnek 7.0’da her zaman 100 | 500 üretiyor.
Bu değişiklik 6.0 ve 7.0 çıktıları arasında sıralama farklarına yol açabiliyor. Nadir durumlarda sıralamadaki değişiklik bir tip hatasının ortaya çıkmasına veya kaybolmasına da neden olabilir. Geçişi kolaylaştırmak için 6.0’a yeni bir --stableTypeOrdering bayrağı eklendi. Bu bayrak, 6.0’ın sıralama davranışını 7.0 ile hizalıyor.
Ekip, bu bayrağın sürekli kullanılmasını önermiyor: kod tabanına bağlı olarak tip denetimi süresine %25’e varan bir yavaşlama getirebiliyor. Bayrak etkinken yeni bir tip hatasıyla karşılaşılırsa, bunun genellikle çıkarım farklarından kaynaklandığı belirtiliyor. Çözüm için sık kullanılan iki yaklaşım şöyle:
- someFunctionCall(/*...*/);
+ someFunctionCall<SomeExplicitType>(/*...*/);
- const someVariable = { /*... some complex object...*/ };
+ const someVariable: SomeExplicitType = { /*... some complex object...*/ };
someFunctionCall(someVariable);
Yani ya çağrıya açık bir tip argümanı vermek ya da geçirilen değişkene açık bir tip ek açıklaması eklemek. Bu bayrağın uzun vadeli bir özellik olarak değil, 6.0 ile 7.0 arasındaki farkları teşhis etmek için tasarlandığı vurgulanıyor.
target ve lib için es2025 seçeneği
TypeScript 6.0, hem target hem de lib için es2025 değerini destekliyor. ES2025 yeni bir JavaScript dil özelliği getirmese de bu hedef, RegExp.escape gibi yerleşik API’ler için yeni tipler ekliyor ve bazı bildirimleri (Promise.try, Iterator metotları ve Set metotları gibi) esnext‘ten es2025‘e taşıyor. Bu çalışma Kenta Moriuchi’nin katkısıyla geldi.
Temporal için yerleşik tipler
Uzun süredir beklenen Temporal önerisi aşama 4’e (stage 4) ulaştı ve gelecekteki bir ECMAScript standardının parçası olacak. TypeScript 6.0 artık Temporal API için yerleşik tipleri içeriyor; bu tipler --target esnext, "lib": ["esnext"] ya da daha dar kapsamlı esnext.temporal ile kullanılabiliyor.
let yesterday = Temporal.Now.instant().subtract({
hours: 24,
});
let tomorrow = Temporal.Now.instant().add({
hours: 24,
});
console.log(`Yesterday: ${yesterday}`);
console.log(`Tomorrow: ${tomorrow}`);
Temporal, birçok çalışma zamanında hâlihazırda kullanılabilir durumda. Bu katkı GitHub kullanıcısı Renegade334 tarafından sağlandı.
Map için “upsert” metotları
Map ile sık karşılaşılan bir desen var: anahtarın var olup olmadığını kontrol etmek ve yoksa varsayılan bir değer atayıp okumak. ECMAScript’in “upsert” önerisi de yakın zamanda aşama 4’e ulaştı ve Map ile WeakMap‘e iki yeni metot ekliyor: getOrInsert ve getOrInsertComputed.
Bu metotlar TypeScript 6.0’da esnext lib’ine dahil edildi. Örneğin:
function processOptions(compilerOptions: Map<string, unknown>) {
let strictValue = compilerOptions.getOrInsert("strict", true);
//...
}
getOrInsertComputed ise varsayılan değerin pahalı olduğu durumlar için tasarlandı. Yalnızca anahtar mevcut değilse çağrılan bir callback alıyor; bu callback’e anahtar da argüman olarak geçiliyor:
someMap.getOrInsertComputed(someKey, computeSomeExpensiveDefaultValue);
Bu güncelleme yine Renegade334 tarafından katkı olarak eklendi.
RegExp.escape
Bir dizgiden düzenli ifade kalıbı oluştururken *, +, ?, (, ) gibi özel karakterlerin kaçırılması gerekir. Aşama 4’e ulaşan RegExp Escaping önerisi ile gelen RegExp.escape bu işi devralıyor:
function matchWholeWord(word: string, text: string) {
const escapedWord = RegExp.escape(word);
const regex = new RegExp(`\\b${escapedWord}\\b`, "g");
return text.match(regex);
}
RegExp.escape, es2025 lib’inde mevcut. Bu çalışma Kenta Moriuchi’nin katkısıyla geldi.
dom lib’i artık dom.iterable ve dom.asynciterable‘ı içeriyor
TypeScript’in lib seçeneği, hedef çalışma zamanının hangi global bildirimlere sahip olduğunu belirlemenizi sağlar. Web ortamları için dom seçeneği kullanılıyor. Daha önce DOM API’lerinin bir kısmı, Iterable ve AsyncIterable‘ı desteklemeyen ortamlar düşünülerek dom.iterable ve dom.asynciterable altına ayrılmıştı. Örneğin NodeList veya HTMLCollection üzerinde iterasyon metotlarını kullanmak için dom.iterable‘ı elle eklemek gerekiyordu.
TypeScript 6.0’da lib.dom.iterable.d.ts ve lib.dom.asynciterable.d.ts içerikleri artık tamamen lib.dom.d.ts‘in içinde. Yapılandırma dosyanızın "lib" dizisinde bu isimlere referans vermeye devam edebilirsiniz; ama artık boş dosyalar. Böylece:
// TypeScript 6.0 öncesi: "lib": ["dom", "dom.iterable"] gerekiyordu.
// Artık yalnızca "lib": ["dom"] yeterli.
for (const element of document.querySelectorAll("div")) {
console.log(element.textContent);
}
Sonuç
TypeScript 6.0 büyük mimari sıçramayı değil, mevcut JavaScript tabanlı derleyicinin son sürümü olarak Go tabanlı 7.0’a geçişi düzleştirmeyi hedefliyor. Sıralama tutarlılığı için gelen --stableTypeOrdering, bağlam duyarlılığındaki iyileştirmeler, #/ ile başlayan subpath import desteği, --moduleResolution bundler ile --module commonjs kombinasyonu ve Temporal, RegExp.escape, upsert metotları gibi yeni ECMAScript API’leri için yerleşik tipler bu sürümün öne çıkan başlıkları.
Kaynaklar ve İleri Okuma
- Announcing TypeScript 6.0 – Microsoft DevBlogs
- TypeScript resmi sitesi
- TypeScript’in Go ile yeniden yazımına dair duyuru
- TypeScript 7 ilerleme güncellemesi
- TypeScript Native Preview – VS Code eklentisi
- @typescript/native-preview paketi
- Generic JSX çağrılarındaki tip denetimi PR’ı
--stableTypeOrderingPR’ı--moduleResolution bundlerile--module commonjsPR’ı- Node.js paket alan referansı (subpath imports dahil)
- Node.js’te
#/subpath import desteği PR’ı - Mateusz Burzyński (Andarist)
- magic-akari
- TypeScript 7.0 Beta: Hız Değil, Asıl Mesaj Daha Büyük
- TypeScript 7.0 RC: Go ile Yeniden Yazıldı, 10 Kat Hızlandı
- TypeScript 7.0 Yayınlandı: Go ile 10 Kat Hız







Yorum gönder