Ders 21 / 23
JavaScript ile Birlikte Çalışma
JavaScript dosyalarının projeye alınması ve denetlenmesi, açıklamalarla tipleme, dosya düzeyinde denetim yönergeleri ve kademeli geçiş stratejisi.
İçindekiler
Önceki ders, tipsiz bir kütüphaneyi dışarıdan tiplemenin yolunu kurdu. Projenin kendi JavaScript dosyaları başka bir sorundur: var olan bir kod tabanı bir gecede dönüştürülemez.
TypeScript bu geçişi destekleyecek biçimde tasarlanmıştır. Her JavaScript dosyası aynı zamanda geçerli bir TypeScript girdisidir; denetim düzeyi ise proje ve dosya bazında ayarlanabilir. Bu ders geçişin araçlarını ve sırasını ele alır.
JavaScript Dosyalarını Projeye Almak
İki ayrı seçenek vardır ve karıştırılmaları sık görülür.
allowJs, JavaScript dosyalarının projeye alınmasını sağlar: derleyici onları okur,
dışa aktardıkları adları bilir ve TypeScript dosyalarından içe aktarılmalarına izin verir.
checkJs, bu dosyaların tip denetiminden geçmesini sağlar.
{ "compilerOptions": { "target": "es2022", "module": "nodenext", "moduleResolution": "nodenext", "strict": true, "allowJs": true, "checkJs": false, "noEmit": true }, "include": ["src"] }
Proje kökünde { "name": "olcum-gecis", "type": "module", "version": "1.0.0" } içeriğinde
bir package.json bulunsun. src/eski.js, geçiş öncesi koddur:
export function ortalama(kayitlar) { let toplam = 0; for (const k of kayitlar) { toplam += k.deger; } return toplam / kayitlar.length; }
src/yeni.ts onu kullanır:
import { ortalama } from "./eski.js"; const kayitlar = [{ deger: 21.4 }, { deger: 22.1 }]; const sonuc: number = ortalama(kayitlar); console.log(sonuc.toFixed(1));
Bu yapılandırmayla derleme hatasız geçer. Ancak güvence yoktur: ortalama fonksiyonunun
parametresi ve dönüş değeri any sayılır, dolayısıyla sonuc bildirimi hiçbir şey
sınamaz.
"checkJs": true yapıldığında:
src/eski.js(1,26): error TS7006: Parameter 'kayitlar' implicitly has an 'any' type.
Katı yapılandırma artık JavaScript dosyasına da uygulanır. Büyük bir kod tabanında bu adım yüzlerce tanı üretir; bu nedenle geçiş genellikle dosya dosya yapılır.
Açıklamalarla Tipleme
JavaScript dosyaları, sözdizimlerini değiştirmeden tiplenebilir. Derleyici, belirli bir biçimdeki açıklama bloklarını tip bildirimi olarak okur:
/** * @typedef {object} Olcum * @property {string} kimlik * @property {number} deger */ /** * @param {readonly Olcum[]} kayitlar * @returns {number} */ export function ortalama(kayitlar) { let toplam = 0; for (const k of kayitlar) { toplam += k.deger; } return toplam / kayitlar.length; }
Bu dosya "checkJs": true ile hatasız denetlenir ve dışa aktardığı fonksiyon artık
tiplenmiştir. Kullanan TypeScript dosyası:
import { ortalama } from "./eski.js"; const kayitlar = [ { kimlik: "s-01", deger: 21.4 }, { kimlik: "s-02", deger: 22.1 }, ]; const sonuc: number = ortalama(kayitlar); console.log(sonuc.toFixed(1)); ortalama([{ kimlik: "s-03", deger: "23.0" }]);
src/yeni.ts(10,29): error TS2322: Type 'string' is not assignable to type 'number'.
Tanı, JavaScript dosyasındaki açıklamadan gelen sözleşmenin gerçekten uygulandığını
gösterir. @typedef, @param ve @returns yönergeleri kursta kurulan tip yazımlarının
açıklama içindeki karşılığıdır; birleşim, dizi ve genellik yazımları da desteklenir.
Bu yöntemin bedeli okunabilirliktir: aynı bilgi daha uzun yazılır ve gövdeden ayrı durur. Kazancı, dosyanın hâlâ sıradan bir JavaScript dosyası olmasıdır — derleme adımı gerektirmeden çalışır. Derleme adımı bulunmayan projelerde ya da geçişin ilk aşamasında uygun bir ara çözümdür.
Dosya Düzeyinde Denetim Yönergeleri
Denetim, dosyanın başına konan bir açıklamayla da açılıp kapatılabilir. "checkJs": false
iken bir dosyaya // @ts-check yazmak, yalnızca o dosyayı denetime alır:
// @ts-check /** * @typedef {object} Olcum * @property {string} kimlik * @property {number} deger */ /** * @param {readonly Olcum[]} kayitlar * @returns {number} */ export function ortalama(kayitlar) { let toplam = 0; for (const k of kayitlar) { toplam += k.kimlik; } return toplam / kayitlar.length; }
src/eski.js(16,5): error TS2322: Type 'string' is not assignable to type 'number'.
Ters yönergesi // @ts-nochecktir ve "checkJs": true iken bir dosyayı denetim dışında
bırakır.
İki yönergenin kullanım yeri farklıdır. // @ts-check, geçişin başında az sayıda dosyayı
denetime almak içindir — proje ayarı kapalı, dosyalar tek tek açılır. // @ts-nocheck,
geçişin sonunda kalan birkaç dosyayı geçici olarak dışarıda bırakmak içindir — proje ayarı
açık, dosyalar tek tek muaf tutulur. İkinci düzen yeğlenir: varsayılan güvenli, muafiyet
görünürdür.
Tek Satırlık Muafiyet
Bazen bir dosyanın tamamı değil, tek bir satır sorunludur. İki yönerge vardır ve aralarındaki fark önemlidir.
// @ts-ignore, sonraki satırdaki tüm tanıları bastırır ve bastıracak bir tanı olmasa da
sessiz kalır. // @ts-expect-error ise sonraki satırda bir tanı beklediğini söyler;
beklenen tanı gelmezse kendisi tanı üretir:
import { ortalama } from "./eski.js"; const kayitlar = [ { kimlik: "s-01", deger: 21.4 }, { kimlik: "s-02", deger: 22.1 }, ]; const sonuc: number = ortalama(kayitlar); console.log(sonuc.toFixed(1)); // @ts-expect-error dizgi deger kabul edilmez ortalama([{ kimlik: "s-03", deger: "23.0" }]); // @ts-expect-error bu satir aslinda gecerli ortalama([{ kimlik: "s-04", deger: 24.0 }]);
src/yeni.ts(13,1): error TS2578: Unused '@ts-expect-error' directive.
Onuncu satırdaki yönerge doğrudur ve tanı üretmez; on üçüncü satırdaki yönerge gereksizdir ve bildirilir.
Bu davranış, // @ts-expect-error yönergesini // @ts-ignore karşısında üstün kılar.
Bastırılan bir hata sonradan düzeltildiğinde — kütüphane güncellendiğinde, tip tanımı
iyileştirildiğinde — @ts-ignore sessizce kalır ve kimse fark etmez. @ts-expect-error
ise “artık gerekli değilim” der. Muafiyetler böylece kendiliğinden temizlenir.
Her iki yönergenin de yanına gerekçe yazılır; yukarıdaki örnekte olduğu gibi yönerge metninin devamı açıklama olarak kabul edilir.
Kademeli Geçiş Sırası
Toplanan araçlar bir sıraya konabilir. Her adım, önceki adımın sağladığı güvenceyi korur:
allowJsaçılır,checkJskapalı kalır. JavaScript dosyaları projeye girer; hiçbir yeni tanı gelmez. Yeni yazılan kod TypeScript olur.- Sık kullanılan modüllerin sözleşmeleri yazılır. Ya
.d.tsdosyasıyla ya da açıklamalarla. En çok içe aktarılan modüller önce ele alınır; her biri, kendisini kullanan tüm dosyalara güvence yayar. - Dosyalar tek tek
// @ts-checkile denetime alınır. Çıkan tanılar düzeltilir. Düzeltilemeyenler// @ts-expect-errorile gerekçelendirilir. checkJsaçılır, kalan dosyalar// @ts-nocheckile muaf tutulur. Varsayılan artık güvenli taraftadır.- Dosyalar
.tsuzantısına taşınır ve açıklamadaki tipler sözdizime çevrilir. - Şemsiye dışındaki katılık bayrakları teker teker açılır. Derleyici Yapılandırması
dersindeki
noUncheckedIndexedAccessveexactOptionalPropertyTypesbu aşamada gelir.
Sıranın ilkesi, her adımda kırmızının sıfırda tutulmasıdır: derleme her zaman temiz geçmeli, yeni tanılar biriktirilmemelidir. Aksi hâlde tanı listesi bir gürültüye dönüşür ve gerçek hatalar arasında kaybolur.
Bir noktada any kullanımı kaçınılmazdır. Kaçış kapıları dersindeki kural burada
uygulanır: any bir geçiş işaretidir. Nerede kaldığı belgelenir ve geçişin sonraki
turlarında daraltılır.
Özet
allowJsJavaScript dosyalarını projeye alır,checkJsonları tip denetimine sokar; ikisi ayrı kararlardır.- Açıklama yazımıyla (
@typedef,@param,@returns) JavaScript dosyaları sözdizimleri değişmeden tiplenir; sözleşme TypeScript tarafında da uygulanır. // @ts-checkve// @ts-nocheckdenetimi dosya düzeyinde açar ve kapatır; muafiyetin görünür olduğu düzen yeğlenir.// @ts-expect-error, beklenen tanı gelmediğindeTS2578üretir ve gereksiz muafiyetlerin temizlenmesini sağlar;// @ts-ignorebunu yapmaz.- Kademeli geçiş, her adımda derlemeyi temiz tutarak ilerler: dosyaları almak, sözleşmeleri yazmak, denetimi açmak, uzantıyı taşımak, katılığı artırmak.
Sonraki Adım
Bu dersteki içe aktarma satırı ./eski.js yazıyordu ve uzantı zorunluydu. Aynı yazım,
kaynak bir TypeScript dosyası olduğunda da değişmez — bu, modül çözümlemenin kurallarından
biridir ve ilk bakışta şaşırtıcıdır. Sonraki ders derleyicinin bir modül adını nasıl bir
dosyaya çevirdiğini, yol eşlemeyi ve çözümleme ayarlarının çıktı üzerindeki etkisini ele
alacak.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.