TypeScript derleyicisinin her hatası bir kod (TS2322 gibi) ve İngilizce bir mesajla gelir. En sık görülenler şunlardır: TS2322 bir değer atandığı tipe uymadığında, TS2345 bir argüman parametre tipine uymadığında, TS2339 tipte olmayan bir özelliğe erişildiğinde, TS7006 parametrenin tipi yazılmadığında, TS18048 ve TS2532 değer undefined olabilecekken kullanıldığında, TS2307 modül bulunamadığında, TS2304 bir ad tanımlı olmadığında ve TS1005 sözdizimi bozuk olduğunda çıkar. Çözüm neredeyse her zaman ya tipi düzeltmek ya da değeri kullanmadan önce denetlemektir.

Aşağıdaki her örneği TypeScript 6.0.3 ile derledik ve yorum satırlarına derleyicinin verdiği mesajı aynen yazdık. 6.0'da strict varsayılan olarak açık olduğu için TS7006 ve TS18048 gibi hatalar ek ayar yapmadan da görünür. Kavramların temeli için temel tipler yazısına bakabilirsiniz.

Hata mesajı nasıl okunur?

Hata mesajı nasıl okunur?

Mesajın ilk satırı neyin yanlış olduğunu söyler, girintili alt satırlar ise "neden?" sorusunu yanıtlar. Resmî "Understanding Errors" sayfası bunu hata ayrıntılandırması olarak anlatır. Bu örnekte iç içe bir alanın tipi uyuşmuyor:

typescript
interface Ayar { sunucu: { port: number } }
const ham = { sunucu: { port: "8080" } };
const ayar: Ayar = ham;
// TS2322: Type '{ sunucu: { port: string; }; }' is not assignable to type 'Ayar'.
bash
h12.ts(3,7): error TS2322: Type '{ sunucu: { port: string; }; }' is not assignable to type 'Ayar'.
  The types of 'sunucu.port' are incompatible between these types.
    Type 'string' is not assignable to type 'number'.

Asıl sorun en alttaki satırda: port metin olarak gelmiş. Mesajlardaki "assignable to" ifadesi "yerine kullanılabilir" anlamındadır ve tek yönlüdür; A tipinin B yerine kullanılabilmesi, B'nin A yerine kullanılabileceği anlamına gelmez. Satır ve sütun numarası (3,7) biçiminde dosya adının yanında yazılır.

TS2322: Type 'X' is not assignable to type 'Y'

Bir değişkene, alana ya da dönüş değerine tipine uymayan bir değer verdiğinizde çıkar. Literal tiplerde de sık görülür:

typescript
let adet: number = "5";
// TS2322: Type 'string' is not assignable to type 'number'.
type Renk = "kirmizi" | "mavi";
const r: Renk = "yesil";
// TS2322: Type '"yesil"' is not assignable to type 'Renk'.

Çözüm: Değeri doğru tipte üretin (let adet = 5) ya da gerçekten dönüştürmeniz gerekiyorsa Number("5") gibi açık bir dönüşüm yapın. Tip tanımı yanlışsa tanımı düzeltin. Hatayı as ile susturmak çoğu zaman sorunu çalışma anına erteler; ne zaman uygun olduğunu type assertion yazısında anlattık.

TS2345: Argument of type 'X' is not assignable to parameter of type 'Y'

TS2322'nin fonksiyon çağrısındaki karşılığıdır: verdiğiniz argüman parametre tipine uymuyor.

typescript
function kare(x: number) {
  return x * x;
}
kare("4");
// TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.

Çözüm: Argümanı dönüştürün (kare(Number(girdi))) ya da fonksiyonun gerçekten birden fazla tip kabul etmesi gerekiyorsa parametreyi number | string gibi bir birleşim tipi yapıp içeride daraltın. Değer formdan veya URL'den geliyorsa dönüştürme sonucunun NaN olabileceğini unutmayın.

TS2339: Property 'x' does not exist on type 'Y'

Tipte tanımlı olmayan bir özelliğe eriştiğinizde çıkar. Ad, var olan bir özelliğe çok benziyorsa derleyici TS2551 koduyla öneride bulunur:

typescript
const kullanici = { ad: "Ece", yas: 30 };
console.log(kullanici.eposta);
// TS2339: Property 'eposta' does not exist on type '{ ad: string; yas: number; }'.
console.log(kullanici.Ad);
// TS2551: Property 'Ad' does not exist on type '{ ad: string; yas: number; }'. Did you mean 'ad'?

Çözüm: Yazım hatasıysa adı düzeltin. Özellik gerçekten bazen varsa tipi buna göre tanımlayın (eposta?: string). Birleşim tiplerinde, özellik yalnızca bazı üyelerde varsa önce "eposta" in nesne gibi bir denetimle daraltın; bu teknikleri narrowing yazısında bulabilirsiniz.

TS7006: Parameter 'x' implicitly has an 'any' type

noImplicitAny açıkken, tipi yazılmamış ve bağlamdan çıkarılamayan bir parametre için çıkar. 6.0'da strict varsayılan olarak açık olduğundan bu hata artık kutudan çıktığı gibi görünür:

typescript
function topla(a, b) {
// TS7006: Parameter 'a' implicitly has an 'any' type.
// TS7006: Parameter 'b' implicitly has an 'any' type.
  return a + b;
}
[1, 2].map(function (x) { return x; });

Son satırdaki x için hata yok: map geri çağrısının parametre tipi bağlamdan (number) çıkarılabiliyor. Çözüm: Parametrelere tip yazın: function topla(a: number, b: number). JavaScript'ten geçiş yapıyorsanız bu hatayı toplu olarak görmeniz normaldir; kademeli yaklaşım için JS projesini TypeScript'e geçirme yazısına bakın.

TS18048, TS2532 ve TS18047: değer undefined ya da null olabilir

strictNullChecks açıkken, undefined veya null olabilecek bir değeri denetlemeden kullandığınızda çıkar. Denemelerimizde derleyici, ifade bir değişken ya da s.not gibi bir özellik erişimi olduğunda TS18048 (undefined) veya TS18047 (null), m.get("a") gibi bir çağrının sonucu olduğunda ise genel TS2532 kodunu verdi:

typescript
interface Siparis {
  not?: string;
}
function ozet(s: Siparis) {
  return s.not.toUpperCase();
// TS18048: 's.not' is possibly 'undefined'.
}
const el = [1, 2, 3].find((x) => x > 5);
console.log(el.toFixed());
// TS18048: 'el' is possibly 'undefined'.
function uzunluk(m: Map<string, number[]>) {
  return m.get("a").length;
// TS2532: Object is possibly 'undefined'.
}
let deger: string | null = null;
deger.length;
// TS18047: 'deger' is possibly 'null'.

find eşleşme bulamazsa, Map.get anahtar yoksa undefined döndürür; derleyici bu olasılığı hatırlatıyor. Çözüm: Değeri kullanmadan önce denetleyin ya da varsayılan değer verin:

typescript
interface Siparis {
  not?: string;
}
function ozet(s: Siparis) {
  return s.not?.toUpperCase() ?? "(not yok)";
}
const el = [1, 2, 3].find((x) => x > 5);
if (el !== undefined) {
  console.log(el.toFixed());
}
function uzunluk(m: Map<string, number[]>) {
  return m.get("a")?.length ?? 0;
}
console.log(ozet({}), uzunluk(new Map())); // (not yok) 0

Değerin kesinlikle var olduğundan eminseniz sondaki ! işaretiyle (el!.toFixed()) derleyiciye bunu söyleyebilirsiniz, ama yanılırsanız hata çalışma anında çıkar. Konunun tamamı null, undefined ve strictNullChecks yazısında.

TS2307: Cannot find module 'x' or its corresponding type declarations

TS2307: Cannot find module 'x' or its corresponding type declarations: Göreli yol yanlışsa, Paket kurulu değilse, Paket kurulu ama tipi yoksa, TypeScript 6.0'a geçtikten sonra...

Import edilen modül ya da onun tip tanımı bulunamadığında çıkar:

typescript
import { hesapla } from "./hesap.js";
// TS2307: Cannot find module './hesap.js' or its corresponding type declarations.
import express from "express";
// TS2307: Cannot find module 'express' or its corresponding type declarations.
  • Göreli yol yanlışsa: Dosya adını, klasörü ve büyük-küçük harfleri kontrol edin. nodenext modunda ES modüllerinde uzantı da şarttır; uzantı eksikse TS2835 ayrı bir hata olarak gelir.
  • Paket kurulu değilse: npm install ile kurun.
  • Paket kurulu ama tipi yoksa: DefinitelyTyped üzerinden tip paketini kurun (npm install --save-dev @types/express) ya da kendi tanım dosyanızı yazın; .d.ts yazısında anlattık.
  • TypeScript 6.0'a geçtikten sonra Node.js modülleri bulunamıyorsa: types varsayılanı boş dizi oldu; "types": ["node"] ekleyin. Bu durumda derleyici TS2591 koduyla doğrudan bu çözümü önerir.

TS2304 ve TS2552: Cannot find name 'x'

Kapsamda tanımlı olmayan bir ad kullandığınızda çıkar. Ad, var olan bir ada benziyorsa TS2552 koduyla öneri gelir:

typescript
console.log(sayac);
// TS2304: Cannot find name 'sayac'.
consol.log("x");
// TS2552: Cannot find name 'consol'. Did you mean 'console'?
const s: Strin = "a";
// TS2552: Cannot find name 'Strin'. Did you mean 'String'?

Çözüm: Yazım hatasını düzeltin, değişkeni tanımlayın ya da import etmeyi unuttuğunuz adı içeri alın. Ad bir ortam API'siyse (örneğin document veya process) sorun genellikle eksik lib ya da types ayarıdır; derleyici bu durumda TS2584 veya TS2591 koduyla hangi ayarı değiştirmeniz gerektiğini söyler. Bkz. target ve lib yazısı.

TS1005: ',' expected (sözdizimi hataları)

1000'li kodlar genellikle sözdizimi hatalarıdır: ayrıştırıcı bir parantez, virgül ya da iki nokta bekliyordur.

typescript
const a = { ad: "x" ;
// TS1005: ',' expected.
function f( {
// TS1005: ':' expected.
// TS1005: '}' expected.

Çözüm: Sözdizimi hataları zincirleme etki yapar; tek bir eksik parantez sonraki satırlarda birkaç hata daha üretebilir. Bu örnekte de iki yazım hatası üç mesaj üretti. Listenin en üstündeki hatayı düzeltip yeniden derleyin, diğerleri çoğu zaman kendiliğinden kaybolur.

Diğer sık hatalar

Diğer sık hatalar: TS2554, TS2741, TS2353, TS2366

Aşağıdaki hataların hepsini aynı derleyiciyle ürettik:

KodMesajın özüTipik çözüm
TS2554Expected 2 arguments, but got 1.Eksik argümanı verin ya da parametreyi isteğe bağlı yapın
TS2741Property 'y' is missing in type ... but required in type 'Nokta'.Eksik alanı ekleyin ya da alanı isteğe bağlı tanımlayın
TS2353Object literal may only specify known properties ...Fazla alanı silin ya da tipe ekleyin
TS2366Function lacks ending return statement ...Tüm dallarda değer döndürün
TS2564Property 'port' has no initializer ...Alanı constructor içinde ya da bildirimde başlatın
TS7053Element implicitly has an 'any' type because expression of type 'string' can't be used to index ...Anahtarı keyof typeof ile daraltın ya da Record tipi kullanın
TS2454Variable 'x' is used before being assigned.Değişkeni kullanmadan önce değer atayın
TS1378Top-level 'await' expressions are only allowed when the 'module' option is set to ...module değerini nodenext veya esnext gibi bir değere çekin
TS2578Unused '@ts-expect-error' directive.Artık gereksiz olan yorumu silin

TS7053 genellikle fiyatlar[ad] gibi bir nesneye string anahtarla erişirken çıkar; doğru araçları index signature ve Record yazısında anlattık. TS2564 ise strictPropertyInitialization bayrağına bağlıdır; ayrıntılar class ve erişim belirleyiciler yazısında.

Hataları susturmak: ne zaman, nasıl?

Bazen hatayı geçici olarak bastırmanız gerekir. Bir satırdan önce // @ts-expect-error yazmak o satırdaki hatayı gizler; altındaki satırda hata kalmadığında ise kendisi TS2578 üretir, böylece unutulmaz. // @ts-ignore böyle bir uyarı vermez. Değeri any yapmak ya da as ile dönüştürmek de hatayı susturur, ama tip denetimini o noktada tamamen kapatır. Bu araçları kalıcı çözüm olarak değil, hatanın kaynağını düzeltene kadar kullanılacak işaretler olarak düşünün; farklarını any, unknown ve never yazısında karşılaştırdık.

Sık Sorulan Sorular

TS2322 ile TS2345 arasındaki fark nedir?

İkisi de "bu tip şuraya uymuyor" demektir. TS2322 atama, dönüş değeri ya da nesne alanında; TS2345 ise fonksiyon çağrısındaki argümanda çıkar. Çözüm yaklaşımı aynıdır.

Neden TS2532 yerine TS18048 görüyorum?

Denemelerimizde derleyici, sorunlu ifade bir değişken ya da s.not gibi bir özellik erişimi olduğunda mesajda adını da yazan TS18048 kodunu verdi; m.get("a") gibi bir çağrının sonucunda ise genel TS2532 mesajı geldi. İkisinin çözümü aynıdır.

TypeScript 6.0'a geçince neden birden çok hata çıktı?

6.0 bazı varsayılanları değiştirdi: strict açık geliyor, types boş dizi, rootDir tsconfig klasörü. Çok sayıda TS7006 ya da TS18048 görüyorsanız strict, Node.js adları bulunamıyorsa types ayarı sebep olabilir. Değişikliklerin listesi TypeScript 6.0 yenilikleri yazısında.

Hata kodunun açıklamasını nerede bulurum?

Mesajın kendisi çoğu zaman yeterince açıklayıcıdır; ilk satırı ve altındaki girintili ayrıntıları birlikte okuyun. Resmî "Understanding Errors" sayfası terimleri ve ayrıntılandırma yapısını açıklar.

Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: TypeScript öğrenme rehberi · TypeScript strict modu · null ve undefined · narrowing ve type guard · any, unknown, never · TypeScript ileri seviye · JavaScript hata mesajları