---
title: 'Tip Daraltma'
source: 'https://academia.sh/tr/kurslar/typescript/tip-daraltma'
course: TypeScript
language: tr
updated: '2026-08-17T18:09:53+00:00'
license: 'CC BY-SA 4.0'
---

# Tip Daraltma

Denetim akışı çözümlemesiyle tip daraltma; typeof, in ve instanceof koruyucuları, doğruluk daraltmasının tuzağı, tip yüklemleri, doğrulama fonksiyonları ve daraltmanın kaybolduğu durumlar.

Önceki derslerde birkaç kez bir birleşim tipi üzerinde sınama yapıldı ve derleyici tipi
tek bir üyeye indirdi. Bu indirgemenin kuralları henüz sıralanmadı.

**Daraltma** (narrowing), derleyicinin bir değerin tipini denetim akışındaki sınamalara
bakarak küçültmesidir. Arkasındaki mekanizmaya **denetim akışı çözümlemesi** (control
flow analysis) denir: derleyici, programın her noktasında hangi koşulların kanıtlanmış
olduğunu izler. Bu ders
hangi sınamaların kanıt sayıldığını, kendi doğrulamanızın derleyiciye nasıl bildirileceğini
ve kanıtın nerede kaybolduğunu ele alır.

## Yerleşik Koruyucular

**Tip koruyucusu** (type guard), bir değerin tipini daraltan sınamadır. En yaygını
`typeof` işlecidir:

```typescript
function bicimle(deger: string | number | null): string {
  if (deger === null) {
    return "-";
  }
  if (typeof deger === "number") {
    return deger.toFixed(1);
  }
  return deger.trim();
}

console.log(bicimle(21.4), bicimle("  s-01  "), bicimle(null));
```

Çıktı `21.4 s-01 -`tir.

Üç dal, üç daraltma adımıdır. `deger === null` sınaması eşitlikle daraltır; ilk `return`
sonrası kalan tip `string | number`dır. `typeof deger === "number"` sınamasından sonra
gövdede tip `number` olur ve `toFixed` çağrılabilir. Son satıra ulaşıldığında kalan tek
olasılık `string`tir; `trim` çağrısı için ek bir sınama gerekmez.

Son adım dikkat ister: derleyici **erken dönüşleri** izler. `return` deyimiyle biten bir
dal, sonraki kodda o olasılığı eler. Programlama Temelleri kursunda tanıtılan koruma
cümlesi kalıbı, tip düzeyinde de kazanç sağlar.

Nesne tipleri için iki koruyucu daha vardır. `in` işleci alan varlığına bakar:

```typescript
type SayisalOlcum = { kimlik: string; deger: number };
type MetinselOlcum = { kimlik: string; metin: string };

function yaz(kayit: SayisalOlcum | MetinselOlcum): string {
  if ("deger" in kayit) {
    return kayit.deger.toFixed(1);
  }
  return kayit.metin.trim();
}

console.log(yaz({ kimlik: "s-01", deger: 21.4 }));
console.log(yaz({ kimlik: "s-02", metin: "  bozuk  " }));
```

Çıktı:

```text
21.4
bozuk
```

`instanceof` işleci ise sınıf örneklerini ayırır:

```typescript
class DosyaKaynagi {
  constructor(readonly yol: string) {}
}

class AgKaynagi {
  constructor(readonly adres: string) {}
}

function tanim(kaynak: DosyaKaynagi | AgKaynagi): string {
  if (kaynak instanceof DosyaKaynagi) {
    return `dosya: ${kaynak.yol}`;
  }
  return `ag: ${kaynak.adres}`;
}

console.log(tanim(new DosyaKaynagi("/veri/olcum.jsonl")));
console.log(tanim(new AgKaynagi("10.0.0.7:9000")));
```

Çıktı:

```text
dosya: /veri/olcum.jsonl
ag: 10.0.0.7:9000
```

Bu üçünün ortak özelliği, hepsinin **çalışma zamanında gerçekten çalışan** sınamalar
olmasıdır. Daraltma, tip sisteminin bir varsayımı değil; koddaki bir sınamanın tip
düzeyine yansımasıdır.

## Doğruluk Daraltmasının Tuzağı

Bir değerin doğruluk değerine bakmak da daraltır, ancak beklenenden fazlasını eler:

```typescript
function etiket(deger: number | undefined): string {
  if (!deger) {
    return "olcum yok";
  }
  return deger.toFixed(1);
}

console.log(etiket(21.4));
console.log(etiket(0));
console.log(etiket(undefined));
```

Çıktı:

```text
21.4
olcum yok
olcum yok
```

Bu dosya tip denetiminden geçer, ama ikinci çıktı yanlıştır: `0` geçerli bir ölçümdür.
JavaScript Temelleri kursunda kurulan yanlış sayılan değerler listesi burada devreye
girer — `0`, `""` ve `NaN` da yanlış sayılır ve `!deger` sınaması onları da eler.

Tip sistemi bu hatayı yakalamaz, çünkü daraltma doğru yapılmıştır: `!deger` bloğundan
sonra tip gerçekten `number`dır. Hata tipte değil, sınamanın seçiminde.

Kural: **`undefined` ve `null` için eşitlik sınaması yazılır.** `if (deger === undefined)`
ya da `if (deger == null)` — ikincisi hem `null` hem `undefined` durumunu eler ve bu, iki
eşittirin savunulabilir tek kullanımıdır.

## Tip Yüklemleri

Doğrulama ayrı bir fonksiyona taşındığında daraltma kaybolur: derleyici, `boolean` dönen
bir fonksiyonun neyi kanıtladığını bilmez. **Tip yüklemi** (type predicate), bu bilgiyi
imzada taşır:

```typescript
interface Olcum {
  kimlik: string;
  deger: number;
  birim: "C" | "Pa" | "%";
}

function olcumMu(deger: unknown): deger is Olcum {
  if (typeof deger !== "object" || deger === null) {
    return false;
  }
  const aday = deger as Record<string, unknown>;
  return (
    typeof aday.kimlik === "string" &&
    typeof aday.deger === "number" &&
    (aday.birim === "C" || aday.birim === "Pa" || aday.birim === "%")
  );
}

function oku(ham: string): string {
  const cozulen: unknown = JSON.parse(ham);
  if (!olcumMu(cozulen)) {
    return "gecersiz kayit";
  }
  return `${cozulen.kimlik}=${cozulen.deger}${cozulen.birim}`;
}

console.log(oku('{"kimlik":"s-01","deger":21.4,"birim":"C"}'));
console.log(oku('{"kimlik":"s-02","deger":"22.1","birim":"C"}'));
console.log(oku('{"kimlik":"s-03","deger":22.1,"birim":"K"}'));
```

Çıktı:

```text
s-01=21.4C
gecersiz kayit
gecersiz kayit
```

Dönüş tipi `boolean` değil `deger is Olcum` yazılmıştır. Bu, derleyiciye şunu söyler:
"bu fonksiyon `true` döndürdüğünde, argümanının `Olcum` olduğunu kabul et." Sonuç, `oku`
içinde `cozulen` değerinin `unknown` olmaktan çıkıp `Olcum` olmasıdır.

Bu, kursun eksenindeki tek noktada toplanır: doğrulama çalışma zamanında yapılır, tip
yüklemi bunun **kanıt olarak** kaydedilmesini sağlar. Model artık dış veriden güvenle
kurulabilir.

Yüklemin bir bedeli vardır. Derleyici, gövdenin gerçekten iddia edileni doğruladığını
sınamaz:

```typescript
interface Olcum {
  kimlik: string;
  deger: number;
}

function olcumMu(deger: unknown): deger is Olcum {
  return typeof deger === "object";
}

const aday: unknown = null;
if (olcumMu(aday)) {
  console.log(aday.deger.toFixed(1));
}
```

Dosya tip denetiminden geçer; çalıştırıldığında:

```text
TypeError: Cannot read properties of null (reading 'deger')
```

Gövde `typeof null === "object"` sonucunu `true` verir ve yanlış bir kanıt üretir. Tip
yüklemi, `as` gibi bir **borçtur**: doğruluğundan yazan sorumludur. Bu nedenle yüklem
gövdeleri kısa tutulur ve sınanır.

## Doğrulama Fonksiyonları

Yüklemin ikinci biçimi, sınamayı geçemeyen değerde hata atar:

```typescript
interface Olcum {
  kimlik: string;
  deger: number;
}

function olcumOldugunuDogrula(deger: unknown): asserts deger is Olcum {
  if (
    typeof deger !== "object" ||
    deger === null ||
    typeof (deger as Record<string, unknown>).kimlik !== "string" ||
    typeof (deger as Record<string, unknown>).deger !== "number"
  ) {
    throw new TypeError("olcum kaydi degil");
  }
}

const cozulen: unknown = JSON.parse('{"kimlik":"s-01","deger":21.4}');
olcumOldugunuDogrula(cozulen);
console.log(cozulen.kimlik, cozulen.deger.toFixed(1));
```

Çıktı `s-01 21.4`tür.

`asserts deger is Olcum` bildirimi, çağrının **normal döndüğü** durumda tipin daralmasını
sağlar. Bir `if` bloğuna gerek kalmaz; çağrıdan sonraki tüm kodda `cozulen` bir `Olcum`dur.

İki biçim arasındaki seçim, geçersiz verinin beklenen bir durum olup olmadığına bağlıdır.
Programlama Temelleri kursundaki Tip Dönüşümü dersinde aynı ayrım yapılmıştı: kullanıcı
girdisinde geçersizlik olağandır ve yüklemle ele alınır; programın kendi ürettiği verinin
geçersizliği istisnaidir ve doğrulama fonksiyonu uygundur.

Bir kısıt vardır: doğrulama fonksiyonunun çağrıldığı ad, açıkça tiplenmiş bir bildirim
olmalıdır. Fonksiyon önce tipsiz bir sabite atanır ve o sabit üzerinden çağrılırsa
derleyici `TS2775` tanısını verir: doğrulama çağrılarında hedefteki her adın açık tip
açıklaması taşıması gerekir.

## Daraltmanın Kaybolduğu Yer

Denetim akışı çözümlemesi, değerin sınamadan sonra değişmediğini varsayabildiği sürece
çalışır. Kapanış içinde bu varsayım geçersizdir:

```typescript
interface Olcum {
  kimlik: string;
  son?: number;
}

function yaz(kayit: Olcum): void {
  if (kayit.son !== undefined) {
    console.log(kayit.son.toFixed(1));
    [1, 2].forEach(() => {
      console.log(kayit.son.toFixed(1));
    });
  }
}

yaz({ kimlik: "s-01", son: 21.4 });
```

```text
n6.ts(10,19): error TS18048: 'kayit.son' is possibly 'undefined'.
```

Sekizinci satır geçerlidir, onuncu satır değildir. Fark, geri çağrının **ne zaman**
çalışacağının bilinmemesidir: `forEach` senkron çalışır ama derleyici bunu bilemez, ve
arada `kayit.son` alanı silinmiş olabilir. Aynı sorun zamanlayıcılarda ve eşzamansız
kodda daha da belirgindir.

Çözüm, daraltılmış değeri yerel bir sabite almaktır:

```typescript
interface Olcum {
  kimlik: string;
  son?: number;
}

function yaz(kayit: Olcum): void {
  const son = kayit.son;
  if (son !== undefined) {
    console.log(son.toFixed(1));
    [1, 2].forEach(() => {
      console.log(son.toFixed(1));
    });
  }
}

yaz({ kimlik: "s-01", son: 21.4 });
```

`const` ile bağlanan bir ad değişemez; derleyici daraltmayı kapanış içine taşıyabilir.
Çıktı üç satır `21.4`tür.

## Özet

- Daraltma, denetim akışındaki sınamaların tip düzeyine yansımasıdır; `typeof`, `in`,
  `instanceof` ve eşitlik sınamaları yerleşik koruyuculardır.
- Doğruluk sınaması `0` ve `""` gibi geçerli değerleri de eler; `null` ve `undefined` için
  eşitlik sınaması yazılır.
- Tip yüklemi (`deger is T`), ayrı bir fonksiyona taşınmış doğrulamanın sonucunu derleyiciye
  bildirir; gövdenin doğruluğu sınanmaz, yüklem bir borçtur.
- Doğrulama fonksiyonu (`asserts deger is T`), geçersiz değerde hata atar ve normal
  döndüğünde tipi daraltır.
- Daraltma kapanış içine taşınmaz; daraltılan değer yerel bir sabite alınarak bu sınır
  aşılır.

## Sonraki Adım

Ölçüm kaydının değişik biçimleri şimdiye kadar elle yazıldı: salt okunur sürüm, alanları
seçmeli olan güncelleme sürümü, yalnızca birkaç alanı taşıyan özet sürüm. Her biri asıl
tipin bir dönüşümüdür ve tip değiştiğinde birlikte güncellenmeleri gerekir. Sonraki ders
bu dönüşümleri tip düzeyinde hesaplayan eşlenmiş tipleri kuracak.
