<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://sonsuzus.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://sonsuzus.github.io/" rel="alternate" type="text/html" /><updated>2026-08-04T07:13:24+00:00</updated><id>https://sonsuzus.github.io/feed.xml</id><title type="html">SonsuzUs</title><subtitle>Programlama ve Yazılım</subtitle><author><name>Sonsuz Us</name></author><entry><title type="html">Arayüzler: Nesne Yönelimli Tasarımın Görünmez Sözleşmeleri</title><link href="https://sonsuzus.github.io/posts/arayuzler-nesne-yonelimli-tasarimin-gorunmez-sozlesmeleri/" rel="alternate" type="text/html" title="Arayüzler: Nesne Yönelimli Tasarımın Görünmez Sözleşmeleri" /><published>2026-08-04T00:00:00+00:00</published><updated>2026-08-04T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/arayuzler-nesne-yonelimli-tasarimin-gorunmez-sozlesmeleri</id><content type="html" xml:base="https://sonsuzus.github.io/posts/arayuzler-nesne-yonelimli-tasarimin-gorunmez-sozlesmeleri/"><![CDATA[<p>Bir orkestrada her müzisyen farklı bir enstrüman çalabilir; ancak şefin verdiği işaretlerin ne anlama geldiğini hepsi bilir. Nesne yönelimli programlamadaki <strong>arayüzler (interfaces)</strong> de benzer biçimde çalışır. Bir sınıfın iç dünyasını yönetmez, fakat dışarıya hangi özellikleri ve davranışları sunması gerektiğini açıkça bildirir. Böylece birbirinden farklı nesneler, ortak bir sözleşmeye uyarak aynı sistem içinde güvenle çalışabilir.
``</p>

<h2 id="arayüz-tam-olarak-nedir">Arayüz tam olarak nedir?</h2>

<p>Arayüz, bir nesnenin <strong>ne yapacağını</strong> tanımlayan; bunu <strong>nasıl yapacağını</strong> ise uygulayıcı sınıfa bırakan soyut bir şablondur. Örneğin <code class="language-plaintext highlighter-rouge">OdemeYontemi</code> isimli bir arayüz, her ödeme yönteminin <code class="language-plaintext highlighter-rouge">ode()</code> metoduna sahip olmasını zorunlu kılabilir. Kredi kartı, banka havalesi veya dijital cüzdan bu işlemi farklı şekilde gerçekleştirir; önemli olan, dışarıdan bakıldığında hepsinin aynı davranışı sunmasıdır.</p>

<p>Bu düşünceyi küme mantığıyla ifade edebiliriz. Bir $I$ arayüzünün zorunlu tuttuğu davranış kümesi $B_I$, bir $C$ sınıfının sunduğu davranış kümesi ise $B_C$ olsun. Sınıfın sözleşmeyi sağlaması için şu koşul geçerlidir:</p>

\[B_I \subseteq B_C\]

<p>Yani sınıf, arayüzde belirtilen bütün üyeleri içermelidir; isterse bunlara yeni özellikler ve metotlar da ekleyebilir.</p>

<h2 id="sınıf-soyut-sınıf-ve-arayüz-farkı">Sınıf, soyut sınıf ve arayüz farkı</h2>

<p>Bu üç yapı sıkça aynı çekmeceye atılsa da görevleri farklıdır:</p>

<table>
  <thead>
    <tr>
      <th>Yapı</th>
      <th>Temel amacı</th>
      <th>Uygulama kodu</th>
      <th>Çoklu kullanım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Sınıf</td>
      <td>Veri ve davranışı gerçekleştirmek</td>
      <td>Tamdır</td>
      <td>Genellikle tek kalıtım</td>
    </tr>
    <tr>
      <td>Soyut sınıf</td>
      <td>Ortak temel ve kısmi uygulama sunmak</td>
      <td>Kısmi olabilir</td>
      <td>Dile bağlıdır</td>
    </tr>
    <tr>
      <td>Arayüz</td>
      <td>Uyulacak sözleşmeyi tanımlamak</td>
      <td>Genellikle davranış bildirir</td>
      <td>Bir sınıf birden fazlasını uygulayabilir</td>
    </tr>
  </tbody>
</table>

<p>Arayüzü bir <strong>priz standardı</strong>, sınıfı ise o prize bağlanan cihaz gibi düşünebiliriz. Televizyon ile kahve makinesinin iç mekanizması aynı değildir; fakat ikisi de uygun fişe sahipse elektrik altyapısıyla iletişim kurabilir.</p>

<h2 id="typescript-ile-sözleşme-oluşturmak">TypeScript ile sözleşme oluşturmak</h2>

<p>Aşağıdaki örnekte bütün bildirim servislerinin uyması gereken yapı tanımlanıyor:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">BildirimServisi</span> <span class="p">{</span>
  <span class="nl">servisAdi</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span>
  <span class="nf">gonder</span><span class="p">(</span><span class="nx">alici</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="nx">mesaj</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="nx">boolean</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">EpostaServisi</span> <span class="k">implements</span> <span class="nx">BildirimServisi</span> <span class="p">{</span>
  <span class="nx">servisAdi</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">E-posta</span><span class="dl">"</span><span class="p">;</span>

  <span class="nf">gonder</span><span class="p">(</span><span class="nx">alici</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="nx">mesaj</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="nx">boolean</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">`</span><span class="p">${</span><span class="nx">alici</span><span class="p">}</span><span class="s2"> adresine gönderildi: </span><span class="p">${</span><span class="nx">mesaj</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span>
    <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nf">kullaniciyiBilgilendir</span><span class="p">(</span>
  <span class="nx">servis</span><span class="p">:</span> <span class="nx">BildirimServisi</span><span class="p">,</span>
  <span class="nx">alici</span><span class="p">:</span> <span class="kr">string</span>
<span class="p">):</span> <span class="k">void</span> <span class="p">{</span>
  <span class="nx">servis</span><span class="p">.</span><span class="nf">gonder</span><span class="p">(</span><span class="nx">alici</span><span class="p">,</span> <span class="dl">"</span><span class="s2">Siparişiniz hazır!</span><span class="dl">"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Buradaki <code class="language-plaintext highlighter-rouge">kullaniciyiBilgilendir</code> fonksiyonu doğrudan <code class="language-plaintext highlighter-rouge">EpostaServisi</code> sınıfına bağımlı değildir. Yalnızca <code class="language-plaintext highlighter-rouge">BildirimServisi</code> sözleşmesini tanır. Daha sonra SMS veya mobil bildirim sınıfı eklendiğinde fonksiyonun değiştirilmesi gerekmez. Kodun yeni davranışlara açılırken mevcut yapıda değişiklik istememesi, <strong>Açık/Kapalı Prensibi</strong> ile uyumludur.</p>

<h2 id="gevşek-bağlılık-neden-değerlidir">Gevşek bağlılık neden değerlidir?</h2>

<p>Bir sınıf başka bir somut sınıfa doğrudan bağımlıysa değişiklikler zincirleme etki yaratabilir. Arayüz kullanıldığında bağımlılık, uygulama ayrıntısına değil soyut sözleşmeye yönelir. Bu yaklaşım <strong>Bağımlılıkların Tersine Çevrilmesi Prensibi</strong>nin temelidir.</p>

<table>
  <thead>
    <tr>
      <th>Doğrudan bağımlılık</th>
      <th>Arayüz tabanlı bağımlılık</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Bileşenler sıkı bağlıdır</td>
      <td>Bileşenler değiştirilebilir</td>
    </tr>
    <tr>
      <td>Testlerde gerçek servis gerekebilir</td>
      <td>Sahte servis kolayca yazılabilir</td>
    </tr>
    <tr>
      <td>Değişiklik riski yüksektir</td>
      <td>Etki alanı daha sınırlıdır</td>
    </tr>
    <tr>
      <td>Yeniden kullanım zordur</td>
      <td>Esneklik daha yüksektir</td>
    </tr>
  </tbody>
</table>

<p>Örneğin test sırasında gerçekten e-posta göndermek yerine aynı arayüzü uygulayan bir <code class="language-plaintext highlighter-rouge">SahteBildirimServisi</code> kullanılabilir. Böylece test hızlı, ücretsiz ve öngörülebilir olur.</p>

<h2 id="her-yere-arayüz-eklenmeli-mi">Her yere arayüz eklenmeli mi?</h2>

<p>Hayır. Tek uygulaması bulunan ve değişme ihtimali düşük, küçük yapılara sırf “kurumsal görünsün” diye arayüz eklemek gereksiz karmaşıklık yaratabilir. Arayüzler özellikle birden fazla uygulama beklendiğinde, dış sistemler soyutlandığında veya bileşenlerin bağımsız test edilmesi gerektiğinde değerlidir.</p>

<p>Kısacası arayüzler yalnızca metot listeleri değildir; ekipler ve bileşenler arasında kurulmuş teknik anlaşmalardır. İyi tasarlanmış bir arayüz, nesnenin iç ayrıntılarını gizlerken beklentileri netleştirir. Kod değiştikçe sözleşme sabit kalabiliyorsa sistem daha esnek, test edilebilir ve sürdürülebilir hâle gelir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="arayüzler" /><category term="nesne yönelimli programlama" /><category term="yazılım tasarımı" /><summary type="html"><![CDATA[Bir orkestrada her müzisyen farklı bir enstrüman çalabilir; ancak şefin verdiği işaretlerin ne anlama geldiğini hepsi bilir. Nesne yönelimli programlamadaki arayüzler (interfaces) de benzer biçimde çalışır. Bir sınıfın iç dünyasını yönetmez, fakat dışarıya hangi özellikleri ve davranışları sunması gerektiğini açıkça bildirir. Böylece birbirinden farklı nesneler, ortak bir sözleşmeye uyarak aynı sistem içinde güvenle çalışabilir.]]></summary></entry><entry><title type="html">Git Tarihçesinde Zaman Yolculuğu: Log, Reset ve Revert</title><link href="https://sonsuzus.github.io/posts/git-tarihcesinde-zaman-yolculugu-log-reset-ve-revert/" rel="alternate" type="text/html" title="Git Tarihçesinde Zaman Yolculuğu: Log, Reset ve Revert" /><published>2026-08-04T00:00:00+00:00</published><updated>2026-08-04T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/git-tarihcesinde-zaman-yolculugu-log-reset-ve-revert</id><content type="html" xml:base="https://sonsuzus.github.io/posts/git-tarihcesinde-zaman-yolculugu-log-reset-ve-revert/"><![CDATA[<p>Bir Git deposunun geçmişi, projenin nasıl geliştiğini anlatan dijital bir seyir defteridir. Her commit; yapılan değişiklikleri, değişikliği yapan kişiyi ve önceki duruma giden bağlantıyı saklar. Yanlış bir commit oluşturduğumuzda paniğe kapılmak yerine bu kayıtları okuyabilir, ardından <code class="language-plaintext highlighter-rouge">reset</code> veya <code class="language-plaintext highlighter-rouge">revert</code> ile güvenli bir zaman yolculuğuna çıkabiliriz.</p>

<p>``</p>

<h2 id="git-geçmişinin-teorik-yapısı">Git geçmişinin teorik yapısı</h2>

<p>Git commit’leri yalnızca sıralı kayıtlar değildir. Her commit, kendisinden önce gelen commit’in kimliğini taşıyan bir düğümdür. Basitleştirilmiş bir geçmiş şöyle gösterilebilir:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>A &lt;- B &lt;- C &lt;- D
               ^
              HEAD
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">HEAD</code>, üzerinde çalıştığımız dalın güncel commit’ini işaret eder. Bir commit kimliği; içerik, yazar, zaman ve üst commit bilgileri kullanılarak üretilen bir özettir. Kavramsal olarak bunu şöyle düşünebiliriz:</p>

\[CommitID = Hash(içerik + yazar + zaman + parent)\]

<p>Bu yapı sayesinde geçmişteki bir commit değiştirilirse onu izleyen kimlikler de değişir. Bu nedenle yayımlanmış geçmişi yeniden yazmak ekip çalışmalarında risklidir.</p>

<h2 id="geçmişi-git-log-ile-okumak">Geçmişi <code class="language-plaintext highlighter-rouge">git log</code> ile okumak</h2>

<p>İlk inceleme aracımız <code class="language-plaintext highlighter-rouge">git log</code> komutudur:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git log
</code></pre></div></div>

<p>Bu komut commit kimliklerini, yazarları, tarihleri ve mesajları gösterir. Daha okunabilir bir görünüm için şu sürüm oldukça kullanışlıdır:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git log <span class="nt">--oneline</span> <span class="nt">--graph</span> <span class="nt">--decorate</span> <span class="nt">--all</span>
</code></pre></div></div>

<p>Buradaki <code class="language-plaintext highlighter-rouge">--oneline</code> kayıtları kısaltır, <code class="language-plaintext highlighter-rouge">--graph</code> dallanmaları görselleştirir, <code class="language-plaintext highlighter-rouge">--decorate</code> dal ve etiket adlarını ekler. Belirli bir dosyanın geçmişini incelemek için ise şunu kullanabiliriz:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git log <span class="nt">--oneline</span> <span class="nt">--</span> src/app.js
</code></pre></div></div>

<p>Commit’in hangi değişiklikleri yaptığını görmek için <code class="language-plaintext highlighter-rouge">git show &lt;commit-id&gt;</code> kullanılabilir. Böylece geri alma kararı vermeden önce “Suçlu gerçekten bu commit mi?” sorusunu yanıtlarız.</p>

<h2 id="reset-mi-revert-mü">Reset mi, revert mü?</h2>

<p>İki komut da geri dönüş sağlar fakat yöntemleri farklıdır:</p>

<table>
  <thead>
    <tr>
      <th>Komut</th>
      <th style="text-align: right">Geçmişi yeniden yazar mı?</th>
      <th style="text-align: right">Yeni commit üretir mi?</th>
      <th>Uygun kullanım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">reset --soft</code></td>
      <td style="text-align: right">Evet</td>
      <td style="text-align: right">Hayır</td>
      <td>Commit’i silip değişiklikleri staged tutmak</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">reset --mixed</code></td>
      <td style="text-align: right">Evet</td>
      <td style="text-align: right">Hayır</td>
      <td>Değişiklikleri çalışma alanında bırakmak</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">reset --hard</code></td>
      <td style="text-align: right">Evet</td>
      <td style="text-align: right">Hayır</td>
      <td>Yerel değişiklikleri tamamen atmak</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">revert</code></td>
      <td style="text-align: right">Hayır</td>
      <td style="text-align: right">Evet</td>
      <td>Paylaşılmış commit’i güvenle geri almak</td>
    </tr>
  </tbody>
</table>

<h3 id="reset-ile-işaretçiyi-taşımak">Reset ile işaretçiyi taşımak</h3>

<p>Son commit mesajı veya içeriği yanlışsa ve henüz uzak depoya gönderilmediyse şu komut kullanılabilir:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git reset <span class="nt">--soft</span> HEAD~1
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">HEAD~1</code>, güncel commit’in bir önceki atasını ifade eder. Commit kaldırılır ancak değişiklikler staging alanında kalır; böylece düzenleyip yeniden commit oluşturabiliriz.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git reset <span class="nt">--hard</span> HEAD~1
</code></pre></div></div>

<p>Bu sürüm hem commit’i hem de dosya değişikliklerini siler. Kaydedilmemiş çalışmalar açısından oldukça tehlikelidir. Kısacası <code class="language-plaintext highlighter-rouge">--hard</code>, Git dünyasının “Emin misin?” diye iki kez sormamız gereken kırmızı düğmesidir.</p>

<h2 id="revert-ile-güvenli-geri-alma">Revert ile güvenli geri alma</h2>

<p>Hatalı commit uzak depoya gönderildiyse geçmişi değiştirmek yerine ters değişiklik oluşturan yeni bir commit eklemek daha güvenlidir:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git revert a1b2c3d
</code></pre></div></div>

<p>Geçmiş başlangıçta $A \rightarrow B \rightarrow C$ ise ve <code class="language-plaintext highlighter-rouge">C</code> geri alınırsa sonuç $A \rightarrow B \rightarrow C \rightarrow C^{-1}$ olur. Yani <code class="language-plaintext highlighter-rouge">C</code> kaybolmaz; etkisini tersine çeviren kayıt eklenir. Bu yaklaşım denetlenebilirliği korur ve ekip arkadaşlarının geçmişiyle çatışmaz.</p>

<h2 id="yanlış-reset-yaptıysak-ne-olacak">Yanlış reset yaptıysak ne olacak?</h2>

<p>Git çoğu zaman kaçış kapısını açık bırakır. <code class="language-plaintext highlighter-rouge">reflog</code>, <code class="language-plaintext highlighter-rouge">HEAD</code> işaretçisinin önceki konumlarını gösterir:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git reflog
git reset <span class="nt">--hard</span> HEAD@<span class="o">{</span>1<span class="o">}</span>
</code></pre></div></div>

<p>İkinci komut, uygun kayıt seçildiğinde bizi reset öncesindeki konuma döndürebilir. Yine de reflog kalıcı bir yedek değildir.</p>

<p>Pratik kural basittir: Önce <code class="language-plaintext highlighter-rouge">log</code> ve <code class="language-plaintext highlighter-rouge">show</code> ile incele, paylaşılmamış geçmişte dikkatli biçimde <code class="language-plaintext highlighter-rouge">reset</code>, paylaşılmış geçmişte ise çoğunlukla <code class="language-plaintext highlighter-rouge">revert</code> kullan. Komutu çalıştırmadan önce <code class="language-plaintext highlighter-rouge">git status</code> kontrolü yapmak da zaman makinesine emniyet kemeri takmak gibidir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="Git" /><category term="Versiyon Kontrolü" /><category term="Hata Yönetimi" /><summary type="html"><![CDATA[Bir Git deposunun geçmişi, projenin nasıl geliştiğini anlatan dijital bir seyir defteridir. Her commit; yapılan değişiklikleri, değişikliği yapan kişiyi ve önceki duruma giden bağlantıyı saklar. Yanlış bir commit oluşturduğumuzda paniğe kapılmak yerine bu kayıtları okuyabilir, ardından reset veya revert ile güvenli bir zaman yolculuğuna çıkabiliriz.]]></summary></entry><entry><title type="html">Pull Request ve Code Review: Kodun Ana Projeye Güvenli Yolculuğu</title><link href="https://sonsuzus.github.io/posts/pull-request-ve-code-review-kodun-ana-projeye-guvenli-yolculugu/" rel="alternate" type="text/html" title="Pull Request ve Code Review: Kodun Ana Projeye Güvenli Yolculuğu" /><published>2026-08-04T00:00:00+00:00</published><updated>2026-08-04T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/pull-request-ve-code-review-kodun-ana-projeye-guvenli-yolculugu</id><content type="html" xml:base="https://sonsuzus.github.io/posts/pull-request-ve-code-review-kodun-ana-projeye-guvenli-yolculugu/"><![CDATA[<p>Bir özellik geliştirdiniz, testleri çalıştırdınız ve kodunuz bilgisayarınızda kusursuz görünüyor. Peki bu kod doğrudan ana projeye eklenmeli mi? Genellikle hayır! Pull Request ve Code Review süreçleri, kodun ana dala ulaşmadan önce teknik doğruluk, okunabilirlik, güvenlik ve ekip standartları açısından denetlendiği bir kalite kapısı oluşturur.
``</p>

<h2 id="pull-request-nedir">Pull Request nedir?</h2>

<p><strong>Pull Request (PR)</strong>, bir dalda yapılan değişikliklerin başka bir dala alınması için oluşturulan resmi bir birleştirme talebidir. GitHub bu adı kullanırken GitLab aynı kavrama <strong>Merge Request</strong> der. İsimler değişse de temel fikir aynıdır: “Değişikliklerimi tamamladım; lütfen inceleyin ve uygunsa ana projeye dahil edin.”</p>

<p>PR yalnızca kod farklarını gösteren bir ekran değildir. Değişikliğin amacı, test yöntemi, ilişkili görevler, ekran görüntüleri ve inceleme konuşmaları için ortak bir çalışma alanıdır. Böylece kodun neden değiştirildiği, aylar sonra bile commit geçmişinden daha rahat anlaşılır.</p>

<p>Tipik akış şöyledir:</p>

<ol>
  <li>Ana daldan yeni bir özellik dalı oluşturulur.</li>
  <li>Değişiklikler küçük ve anlamlı commit’lerle kaydedilir.</li>
  <li>Dal uzak depoya gönderilir.</li>
  <li>Bir Pull Request açılır.</li>
  <li>Otomatik testler ve statik analiz araçları çalışır.</li>
  <li>İnceleyiciler yorum yapar veya değişiklik ister.</li>
  <li>Onaylanan kod ana dalla birleştirilir.</li>
</ol>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git switch main
git pull
git switch <span class="nt">-c</span> feature/kullanici-arama

<span class="c"># Kod değişikliklerinden sonra</span>
git add <span class="nb">.</span>
git commit <span class="nt">-m</span> <span class="s2">"Kullanıcı arama filtresi eklendi"</span>
git push <span class="nt">-u</span> origin feature/kullanici-arama
</code></pre></div></div>

<p>Bu komutlar güncel <code class="language-plaintext highlighter-rouge">main</code> dalından bağımsız bir geliştirme dalı oluşturur, değişiklikleri kaydeder ve PR açılabilmesi için uzak depoya gönderir.</p>

<h2 id="code-review-neden-gereklidir">Code Review neden gereklidir?</h2>

<p><strong>Code Review</strong>, başka bir geliştiricinin değişiklikleri sistematik biçimde değerlendirmesidir. Amaç hata avına çıkıp yazarı köşeye sıkıştırmak değil; ortak kod tabanını iyileştirmek ve ekip içinde bilgi paylaşmaktır. İnceleme sırasında doğruluk, performans, güvenlik, test kapsamı, isimlendirme ve sürdürülebilirlik değerlendirilir.</p>

<p>Basitleştirilmiş bir kalite modeli şöyle düşünülebilir:</p>

\[Q = w_dD + w_tT + w_oO + w_gG\]

<p>Burada $D$ doğruluğu, $T$ test edilebilirliği, $O$ okunabilirliği ve $G$ güvenliği temsil eder. $w$ katsayıları ise projenin öncelikleridir. Örneğin finans uygulamasında güvenliğin ağırlığı, küçük bir tanıtım sitesine göre daha yüksek olabilir.</p>

<table>
  <thead>
    <tr>
      <th>Kontrol alanı</th>
      <th>İnceleyicinin sorusu</th>
      <th>Olası risk</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Doğruluk</td>
      <td>Kod beklenen işi yapıyor mu?</td>
      <td>Yanlış sonuç</td>
    </tr>
    <tr>
      <td>Okunabilirlik</td>
      <td>İsimler ve akış anlaşılır mı?</td>
      <td>Bakım maliyeti</td>
    </tr>
    <tr>
      <td>Testler</td>
      <td>Kritik senaryolar sınanmış mı?</td>
      <td>Regresyon</td>
    </tr>
    <tr>
      <td>Güvenlik</td>
      <td>Girdi doğrulama yeterli mi?</td>
      <td>Veri sızıntısı</td>
    </tr>
    <tr>
      <td>Performans</td>
      <td>Gereksiz işlem veya sorgu var mı?</td>
      <td>Yavaşlama</td>
    </tr>
  </tbody>
</table>

<h2 id="i̇yi-bir-pr-nasıl-hazırlanır">İyi bir PR nasıl hazırlanır?</h2>

<p>İyi PR küçük, odaklı ve açıklayıcıdır. Aynı talepte hem kullanıcı araması eklemek hem dosya yapısını tamamen değiştirmek, incelemeyi zorlaştırır. Büyük PR’larda bilişsel yük artar; gözden kaçan hata olasılığı da yükselir. Kabaca inceleme etkinliğini</p>

\[E \propto \frac{1}{S}\]

<p>şeklinde düşünebiliriz. Burada $S$, değişiklik boyutudur. Bu kesin bir fizik yasası değildir; küçük değişikliklerin daha dikkatli incelenebildiğini anlatan pratik bir modeldir.</p>

<p>PR açıklamasında şu bilgiler bulunmalıdır:</p>

<ul>
  <li>Değişikliğin amacı ve kapsamı</li>
  <li>İlgili görev veya hata kaydı</li>
  <li>Değişikliğin nasıl test edildiği</li>
  <li>Arayüz değiştiyse ekran görüntüsü</li>
  <li>Bilinen sınırlamalar ve riskler</li>
</ul>

<h2 id="yapıcı-inceleme-kültürü">Yapıcı inceleme kültürü</h2>

<p>Yorumlar kişiye değil koda yöneltilmelidir. “Bunu yanlış yazmışsın” yerine “Bu koşul boş değer geldiğinde hata üretebilir; burada erken dönüş kullanabilir miyiz?” demek daha yapıcıdır. Yazar da her yorumu saldırı olarak görmemeli, ancak gerekçesini açıklayamadığı önerileri körü körüne uygulamamalıdır.</p>

<table>
  <thead>
    <tr>
      <th>Zayıf yaklaşım</th>
      <th>Yapıcı yaklaşım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>“Bu kod kötü.”</td>
      <td>“Bu fonksiyonu bölmek okunabilirliği artırabilir.”</td>
    </tr>
    <tr>
      <td>“Böyle yapılmaz.”</td>
      <td>“Projedeki mevcut servis desenini kullanabilir miyiz?”</td>
    </tr>
    <tr>
      <td>Sessizce onaylamak</td>
      <td>Kritik senaryoları ve testleri doğrulamak</td>
    </tr>
  </tbody>
</table>

<p>Sonuç olarak Pull Request bir izin ekranı, Code Review ise bürokratik bir engel değildir. İkisi birlikte hataları erken yakalayan, ekip bilgisini çoğaltan ve ana dalı güvenilir tutan bir mühendislik pratiğidir. Sağlıklı ekiplerde hedef, kimin haklı olduğunu kanıtlamak değil; kodu birlikte daha doğru, anlaşılır ve sürdürülebilir hâle getirmektir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="Git" /><category term="Pull Request" /><category term="Code Review" /><summary type="html"><![CDATA[Bir özellik geliştirdiniz, testleri çalıştırdınız ve kodunuz bilgisayarınızda kusursuz görünüyor. Peki bu kod doğrudan ana projeye eklenmeli mi? Genellikle hayır! Pull Request ve Code Review süreçleri, kodun ana dala ulaşmadan önce teknik doğruluk, okunabilirlik, güvenlik ve ekip standartları açısından denetlendiği bir kalite kapısı oluşturur.]]></summary></entry><entry><title type="html">Temel Veri Tipleriyle Güvenli Kodun Temelleri</title><link href="https://sonsuzus.github.io/posts/temel-veri-tipleriyle-guvenli-kodun-temelleri/" rel="alternate" type="text/html" title="Temel Veri Tipleriyle Güvenli Kodun Temelleri" /><published>2026-08-04T00:00:00+00:00</published><updated>2026-08-04T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/temel-veri-tipleriyle-guvenli-kodun-temelleri</id><content type="html" xml:base="https://sonsuzus.github.io/posts/temel-veri-tipleriyle-guvenli-kodun-temelleri/"><![CDATA[<p>Bir programın dünyayı nasıl algıladığını hiç düşündünüz mü? Bizim için yaş, isim ve ışığın açık olup olmadığı farklı kavramlardır. Bilgisayar açısından da bunlar sırasıyla sayı, metin ve mantıksal değer olarak temsil edilir. Temel veri tipleri, verinin anlamını belirleyerek yanlış değerlerin daha kod çalışmadan yakalanmasını sağlar. Kısacası tipler, değişkenlerin kapısında bekleyen seçici güvenlik görevlileridir.</p>

<p>``</p>

<h2 id="temel-veri-tipi-nedir">Temel veri tipi nedir?</h2>

<p>Bir veri tipi, bellekte saklanan değerin nasıl yorumlanacağını ve üzerinde hangi işlemlerin yapılabileceğini tanımlar. Örneğin <code class="language-plaintext highlighter-rouge">10</code> sayısına <code class="language-plaintext highlighter-rouge">5</code> eklemek matematiksel toplama üretirken, <code class="language-plaintext highlighter-rouge">"10"</code> metnine <code class="language-plaintext highlighter-rouge">"5"</code> eklemek çoğu dilde <code class="language-plaintext highlighter-rouge">"105"</code> sonucunu verir.</p>

<p>Bir değişkeni matematiksel olarak değer kümesiyle ifade edebiliriz. <code class="language-plaintext highlighter-rouge">boolean</code> tipindeki bir $b$ değişkeninin alabileceği değerler şöyledir:</p>

\[b \in \{true, false\}\]

<p>Benzer biçimde, 0 ile 120 arasında sınırlandırılmış bir yaş değeri için hedeflenen küme şudur:</p>

\[yas \in \mathbb{Z}, \quad 0 \le yas \le 120\]

<p>Tip sistemi ilk bölümde değerin sayı olmasını garanti edebilir. Aralık gibi daha özel iş kuralları ise doğrulama kodları veya gelişmiş tip teknikleri gerektirir.</p>

<h2 id="en-yaygın-temel-tipler">En yaygın temel tipler</h2>

<table>
  <thead>
    <tr>
      <th>Tip</th>
      <th>Örnek</th>
      <th>Kullanım alanı</th>
      <th>Uygun olmayan değer</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">number</code></td>
      <td><code class="language-plaintext highlighter-rouge">42</code>, <code class="language-plaintext highlighter-rouge">3.14</code></td>
      <td>Yaş, fiyat, puan</td>
      <td><code class="language-plaintext highlighter-rouge">"kırk iki"</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">string</code></td>
      <td><code class="language-plaintext highlighter-rouge">"Ada"</code></td>
      <td>İsim, açıklama, adres</td>
      <td>Sayısal hesaplama</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">boolean</code></td>
      <td><code class="language-plaintext highlighter-rouge">true</code></td>
      <td>Açık/kapalı durumları</td>
      <td><code class="language-plaintext highlighter-rouge">"belki"</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">null</code></td>
      <td><code class="language-plaintext highlighter-rouge">null</code></td>
      <td>Bilinçli olarak boş değer</td>
      <td>Gerçek veri</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">undefined</code></td>
      <td><code class="language-plaintext highlighter-rouge">undefined</code></td>
      <td>Henüz atanmamış değer</td>
      <td>Kesin sonuç</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">bigint</code></td>
      <td><code class="language-plaintext highlighter-rouge">9007199254740993n</code></td>
      <td>Çok büyük tam sayılar</td>
      <td>Ondalıklı işlemler</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">symbol</code></td>
      <td><code class="language-plaintext highlighter-rouge">Symbol("id")</code></td>
      <td>Benzersiz anahtarlar</td>
      <td>Kullanıcı metni</td>
    </tr>
  </tbody>
</table>

<p><code class="language-plaintext highlighter-rouge">null</code> ve <code class="language-plaintext highlighter-rouge">undefined</code> birbirine benzese de aynı şeyi anlatmaz. <code class="language-plaintext highlighter-rouge">null</code>, geliştiricinin bilinçli biçimde “burada değer yok” demesidir. <code class="language-plaintext highlighter-rouge">undefined</code> ise değerin henüz tanımlanmadığını belirtir. Bu ayrım, özellikle API yanıtlarında oldukça önemlidir.</p>

<h2 id="tip-kısıtlaması-neden-güvenlidir">Tip kısıtlaması neden güvenlidir?</h2>

<p>Dinamik tipli JavaScript’te aşağıdaki değişken önce sayı, ardından metin olabilir:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">let</span> <span class="nx">puan</span> <span class="o">=</span> <span class="mi">90</span><span class="p">;</span>
<span class="nx">puan</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">doksan</span><span class="dl">"</span><span class="p">;</span>
</code></pre></div></div>

<p>Kod sözdizimi açısından geçerlidir; ancak daha sonra <code class="language-plaintext highlighter-rouge">puan / 2</code> işlemi yapılırsa beklenmeyen bir sonuç oluşabilir. TypeScript ile değişkenin kabul edeceği değer türü baştan belirtilir:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">let</span> <span class="nx">puan</span><span class="p">:</span> <span class="kr">number</span> <span class="o">=</span> <span class="mi">90</span><span class="p">;</span>
<span class="nx">puan</span> <span class="o">=</span> <span class="mi">100</span><span class="p">;</span>       <span class="c1">// Geçerli</span>
<span class="c1">// puan = "doksan"; // Derleme hatası</span>

<span class="kd">const</span> <span class="nx">basariliMi</span><span class="p">:</span> <span class="nx">boolean</span> <span class="o">=</span> <span class="nx">puan</span> <span class="o">&gt;=</span> <span class="mi">50</span><span class="p">;</span>
<span class="kd">const</span> <span class="nx">mesaj</span><span class="p">:</span> <span class="kr">string</span> <span class="o">=</span> <span class="nx">basariliMi</span> <span class="p">?</span> <span class="dl">"</span><span class="s2">Tebrikler!</span><span class="dl">"</span> <span class="p">:</span> <span class="dl">"</span><span class="s2">Tekrar dene</span><span class="dl">"</span><span class="p">;</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">puan</code> yalnızca sayı, <code class="language-plaintext highlighter-rouge">basariliMi</code> yalnızca mantıksal değer ve <code class="language-plaintext highlighter-rouge">mesaj</code> yalnızca metin kabul eder. Hatalı atama yorumdan çıkarılırsa TypeScript, program çalıştırılmadan geliştiriciyi uyarır. Böylece hata üretim ortamında kullanıcıyla tanışmadan önce yakalanır.</p>

<h2 id="tip-çıkarımı-ve-açık-tanımlama">Tip çıkarımı ve açık tanımlama</h2>

<p>TypeScript her zaman tipin açıkça yazılmasını istemez:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">let</span> <span class="nx">kullaniciAdi</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">deniz</span><span class="dl">"</span><span class="p">;</span> <span class="c1">// string olarak çıkarılır</span>
<span class="kd">let</span> <span class="nx">girisSayisi</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>        <span class="c1">// number olarak çıkarılır</span>
<span class="kd">let</span> <span class="nx">aktif</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>           <span class="c1">// boolean olarak çıkarılır</span>
</code></pre></div></div>

<p>Bu mekanizmaya <strong>tip çıkarımı</strong> denir. Başlangıç değeri tip hakkında yeterli bilgi veriyorsa kısa ve okunaklı kod sağlar. Fonksiyon parametrelerinde ise açık tip kullanmak daha güvenlidir:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">indirimliFiyat</span><span class="p">(</span><span class="nx">fiyat</span><span class="p">:</span> <span class="kr">number</span><span class="p">,</span> <span class="nx">oran</span><span class="p">:</span> <span class="kr">number</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span>
  <span class="k">return</span> <span class="nx">fiyat</span> <span class="o">*</span> <span class="p">(</span><span class="mi">1</span> <span class="o">-</span> <span class="nx">oran</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">sonuc</span> <span class="o">=</span> <span class="nf">indirimliFiyat</span><span class="p">(</span><span class="mi">500</span><span class="p">,</span> <span class="mf">0.2</span><span class="p">);</span> <span class="c1">// 400</span>
</code></pre></div></div>

<p>Formül $F_{son} = F \times (1-r)$ şeklindedir. Tipler <code class="language-plaintext highlighter-rouge">fiyat</code> ve <code class="language-plaintext highlighter-rouge">oran</code> değerlerinin metin olmasını engeller; fakat oranın 0 ile 1 arasında olduğunu tek başına doğrulamaz. Bu nedenle çalışma zamanı kontrolleri tip sisteminin tamamlayıcısıdır.</p>

<h2 id="sonuç">Sonuç</h2>

<p>Temel veri tipleri yalnızca sözdizimsel ayrıntılar değildir; programın veri sözleşmesini oluşturur. Doğru tip seçimi otomatik tamamlama kalitesini artırır, yeniden düzenlemeyi kolaylaştırır ve hataları erkenden görünür kılar. Değişkene “her şeyi kabul et” demek pratik görünebilir, fakat güvenli yazılım çoğu zaman doğru yerde nazikçe “hayır” diyebilen yazılımdır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="veri tipleri" /><category term="TypeScript" /><category term="tip güvenliği" /><summary type="html"><![CDATA[Bir programın dünyayı nasıl algıladığını hiç düşündünüz mü? Bizim için yaş, isim ve ışığın açık olup olmadığı farklı kavramlardır. Bilgisayar açısından da bunlar sırasıyla sayı, metin ve mantıksal değer olarak temsil edilir. Temel veri tipleri, verinin anlamını belirleyerek yanlış değerlerin daha kod çalışmadan yakalanmasını sağlar. Kısacası tipler, değişkenlerin kapısında bekleyen seçici güvenlik görevlileridir.]]></summary></entry><entry><title type="html">Tip Çıkarımı: Derleyicinin Kodunuzdaki Sessiz Dedektifliği</title><link href="https://sonsuzus.github.io/posts/tip-cikarimi-derleyicinin-kodunuzdaki-sessiz-dedektifligi/" rel="alternate" type="text/html" title="Tip Çıkarımı: Derleyicinin Kodunuzdaki Sessiz Dedektifliği" /><published>2026-08-04T00:00:00+00:00</published><updated>2026-08-04T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/tip-cikarimi-derleyicinin-kodunuzdaki-sessiz-dedektifligi</id><content type="html" xml:base="https://sonsuzus.github.io/posts/tip-cikarimi-derleyicinin-kodunuzdaki-sessiz-dedektifligi/"><![CDATA[<p>Bir değişken tanımlarken veri türünü yazmadığınız hâlde editörünüzün onun sayı mı, metin mi yoksa daha karmaşık bir nesne mi olduğunu bilmesi sihir gibi görünebilir. Aslında perde arkasında çalışan mekanizma <strong>tip çıkarımıdır</strong>. Derleyici, atanan ifadeyi inceleyerek uygun türü belirler; böylece kod kısalırken statik tip güvenliği büyük ölçüde korunur.
``</p>

<h2 id="tip-çıkarımı-tam-olarak-nedir">Tip çıkarımı tam olarak nedir?</h2>

<p>Tip çıkarımı, derleyicinin bir ifadenin veri türünü programcının açık bildirimine ihtiyaç duymadan hesaplamasıdır. Basit bir modelle değişkenin türünü şöyle gösterebiliriz:</p>

\[T(x) = T(e)\]

<p>Burada $x$ değişkeni, $e$ ise ona atanan ifadedir. Örneğin <code class="language-plaintext highlighter-rouge">x = 42</code> ifadesinde derleyici, <code class="language-plaintext highlighter-rouge">42</code> sabitinin türünü inceler ve dile bağlı olarak <code class="language-plaintext highlighter-rouge">int</code>, <code class="language-plaintext highlighter-rouge">Int</code> veya benzeri bir tür seçer.</p>

<p>Bu işlem çoğunlukla <strong>derleme zamanında</strong> gerçekleşir. Yani program çalışırken tür tahmini yapılmaz; derleyici daha çalıştırılabilir dosya üretilmeden önce kararını verir. Bu nedenle tip çıkarımı, dinamik tiplemeyle aynı şey değildir.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Tip çıkarımı</th>
      <th>Dinamik tipleme</th>
      <th>Açık statik tipleme</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Tür ne zaman belirlenir?</td>
      <td>Derleme zamanında</td>
      <td>Çalışma zamanında</td>
      <td>Programcı yazarken</td>
    </tr>
    <tr>
      <td>Türü kim belirtir?</td>
      <td>Derleyici</td>
      <td>Çalışan program</td>
      <td>Geliştirici</td>
    </tr>
    <tr>
      <td>Sonradan farklı tür atanabilir mi?</td>
      <td>Genellikle hayır</td>
      <td>Genellikle evet</td>
      <td>Hayır</td>
    </tr>
    <tr>
      <td>Kod uzunluğu</td>
      <td>Kısa</td>
      <td>Kısa</td>
      <td>Daha uzun</td>
    </tr>
    <tr>
      <td>Erken hata yakalama</td>
      <td>Güçlü</td>
      <td>Daha sınırlı</td>
      <td>Güçlü</td>
    </tr>
  </tbody>
</table>

<h2 id="derleyici-nasıl-karar-verir">Derleyici nasıl karar verir?</h2>

<p>Derleyici önce sağ taraftaki ifadeyi analiz eder. Sabitleri, fonksiyonların dönüş türlerini, operatörleri ve varsa genel tür kısıtlarını değerlendirir. Ardından bulunan türü değişkenle eşleştirir.</p>

<p>C# dilindeki şu örneğe bakalım:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">var</span> <span class="n">puan</span> <span class="p">=</span> <span class="m">95</span><span class="p">;</span>             <span class="c1">// Derleyici türü int olarak çıkarır.</span>
<span class="kt">var</span> <span class="n">mesaj</span> <span class="p">=</span> <span class="s">"Başarılı"</span><span class="p">;</span>   <span class="c1">// Tür string olur.</span>
<span class="kt">var</span> <span class="n">oran</span> <span class="p">=</span> <span class="m">0.85</span><span class="p">;</span>           <span class="c1">// Varsayılan olarak double seçilir.</span>
</code></pre></div></div>

<p>Buradaki <code class="language-plaintext highlighter-rouge">var</code>, değişkenin türsüz olduğu anlamına gelmez. <code class="language-plaintext highlighter-rouge">puan</code>, derleme sonrasında kesin biçimde <code class="language-plaintext highlighter-rouge">int</code> kabul edilir. Bu yüzden aşağıdaki atama geçersizdir:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">var</span> <span class="n">puan</span> <span class="p">=</span> <span class="m">95</span><span class="p">;</span>
<span class="n">puan</span> <span class="p">=</span> <span class="s">"Doksan beş"</span><span class="p">;</span> <span class="c1">// Hata: string, int değişkenine atanamaz.</span>
</code></pre></div></div>

<p>Derleyicinin ilk değerden hareket etmesi, türün daha sonra sürekli değişebileceği anlamına gelmez. İlk ifade yalnızca başlangıçtaki <strong>kanıttır</strong>; ulaşılan tür ise değişkenin kapsamı boyunca geçerli sözleşmedir.</p>

<h2 id="fonksiyonlarda-ve-koleksiyonlarda-çıkarım">Fonksiyonlarda ve koleksiyonlarda çıkarım</h2>

<p>Tip çıkarımı yalnızca basit değişkenlerle sınırlı değildir. Genel fonksiyon çağrılarında tür parametreleri de argümanlardan bulunabilir:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">ilkEleman</span><span class="o">&lt;</span><span class="nx">T</span><span class="o">&gt;</span><span class="p">(</span><span class="nx">liste</span><span class="p">:</span> <span class="nx">T</span><span class="p">[]):</span> <span class="nx">T</span> <span class="p">{</span>
  <span class="k">return</span> <span class="nx">liste</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">sonuc</span> <span class="o">=</span> <span class="nf">ilkEleman</span><span class="p">([</span><span class="mi">10</span><span class="p">,</span> <span class="mi">20</span><span class="p">,</span> <span class="mi">30</span><span class="p">]);</span>
<span class="c1">// T, number olarak çıkarılır; sonuc da number olur.</span>
</code></pre></div></div>

<p>Derleyici burada dizinin elemanlarını inceler ve şu ilişkiyi kurar:</p>

\[T([10,20,30]) = number[] \Rightarrow T = number\]

<p>Bu yaklaşım, genel ve yeniden kullanılabilir kod yazmayı kolaylaştırır. Programcı her çağrıda <code class="language-plaintext highlighter-rouge">&lt;number&gt;</code> yazmak zorunda kalmaz.</p>

<h2 id="ne-zaman-açık-tür-yazılmalı">Ne zaman açık tür yazılmalı?</h2>

<p>Tip çıkarımı faydalı olsa da her yerde kullanmak okunabilirliği artırmaz. Değer türü ilk bakışta belliyse çıkarım idealdir. Karmaşık API dönüşlerinde, değişkenin niyetini vurgulamak gerektiğinde veya daha geniş bir tür hedeflendiğinde açık bildirim daha anlaşılır olabilir.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">IEnumerable</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="n">puanlar</span> <span class="p">=</span> <span class="k">new</span> <span class="n">List</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="p">{</span> <span class="m">70</span><span class="p">,</span> <span class="m">85</span><span class="p">,</span> <span class="m">100</span> <span class="p">};</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">var</code> kullanmak mümkün olsa da açık tür, kodun yalnızca <code class="language-plaintext highlighter-rouge">List&lt;int&gt;</code> uygulamasına değil <code class="language-plaintext highlighter-rouge">IEnumerable&lt;int&gt;</code> sözleşmesine dayandığını anlatır.</p>

<p>Kısacası tip çıkarımı, geliştiricinin yerine rastgele karar veren bir mekanizma değil; ifadelerden, kısıtlardan ve dil kurallarından mantıksal sonuç üreten bir derleyici özelliğidir. Doğru kullanıldığında kodu sadeleştirir, tekrarları azaltır ve tip güvenliğinden vazgeçmeden daha akıcı programlama sağlar.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="tip çıkarımı" /><category term="derleyici" /><category term="statik tipleme" /><summary type="html"><![CDATA[Bir değişken tanımlarken veri türünü yazmadığınız hâlde editörünüzün onun sayı mı, metin mi yoksa daha karmaşık bir nesne mi olduğunu bilmesi sihir gibi görünebilir. Aslında perde arkasında çalışan mekanizma tip çıkarımıdır. Derleyici, atanan ifadeyi inceleyerek uygun türü belirler; böylece kod kısalırken statik tip güvenliği büyük ölçüde korunur.]]></summary></entry><entry><title type="html">TypeScript Felsefesi: JavaScript Dünyasında Statik Tip Güvenliği</title><link href="https://sonsuzus.github.io/posts/typescript-felsefesi-javascript-dunyasinda-statik-tip-guvenligi/" rel="alternate" type="text/html" title="TypeScript Felsefesi: JavaScript Dünyasında Statik Tip Güvenliği" /><published>2026-08-04T00:00:00+00:00</published><updated>2026-08-04T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/typescript-felsefesi-javascript-dunyasinda-statik-tip-guvenligi</id><content type="html" xml:base="https://sonsuzus.github.io/posts/typescript-felsefesi-javascript-dunyasinda-statik-tip-guvenligi/"><![CDATA[<p>JavaScript, geliştiriciye büyük bir hareket özgürlüğü sunar; ancak bu özgürlük bazen üretim ortamında patlayan küçük sürpriz paketlerine dönüşebilir. TypeScript’in temel felsefesi, JavaScript’in esnekliğini ortadan kaldırmak değil, program çalışmadan önce olası hataları görünür hâle getiren bir düşünme katmanı eklemektir. C ve C++ dünyasındaki statik tip denetimini anımsatan bu yaklaşım, dinamik web ekosistemine daha güvenli ve ölçeklenebilir bir geliştirme modeli kazandırır.
``</p>

<h2 id="statik-ve-dinamik-tip-sistemleri">Statik ve dinamik tip sistemleri</h2>

<p>Bir değişkenin hangi değerleri taşıyabileceği, programlama dilinin tip sistemi tarafından belirlenir. C++ gibi statik tipli bir dilde değişkenin tipi derleme sırasında bilinir ve uygunsuz işlemler reddedilir. JavaScript’te ise tip, değişkenden çok çalışma anındaki değere aittir.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">let</span> <span class="nx">value</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
<span class="nx">value</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">on</span><span class="dl">"</span><span class="p">;</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">value</span> <span class="o">*</span> <span class="mi">2</span><span class="p">);</span> <span class="c1">// NaN</span>
</code></pre></div></div>

<p>Bu kod JavaScript açısından geçerlidir. Sorun ancak işlem çalıştırıldığında ortaya çıkar. TypeScript aynı belirsizliği derleme aşamasına taşır:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">let</span> <span class="nx">value</span><span class="p">:</span> <span class="kr">number</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
<span class="nx">value</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">on</span><span class="dl">"</span><span class="p">;</span> <span class="c1">// Hata: string, number tipine atanamaz</span>
</code></pre></div></div>

<p>Buradaki amaç programı yavaşlatan çalışma zamanı kontrolleri eklemek değildir. TypeScript tipleri JavaScript çıktısı üretilirken siler. Başka bir ifadeyle tip sistemi, çalışan programın değil, program hakkındaki bilgimizin parçasıdır.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>JavaScript</th>
      <th>TypeScript</th>
      <th>C/C++</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Tip denetimi</td>
      <td>Çalışma zamanında ağırlıklı</td>
      <td>Derleme zamanında</td>
      <td>Derleme zamanında</td>
    </tr>
    <tr>
      <td>Tip açıklaması</td>
      <td>Zorunlu değil</td>
      <td>İsteğe bağlı ve çıkarımlı</td>
      <td>Genellikle açık</td>
    </tr>
    <tr>
      <td>Çıktı</td>
      <td>Doğrudan çalışır</td>
      <td>JavaScript’e çevrilir</td>
      <td>Makine koduna derlenir</td>
    </tr>
    <tr>
      <td>Bellek güvenliği</td>
      <td>Motor tarafından yönetilir</td>
      <td>JavaScript ile aynı</td>
      <td>Geliştiricinin sorumluluğu olabilir</td>
    </tr>
    <tr>
      <td>Mevcut kodla uyum</td>
      <td>Doğal</td>
      <td>Kademeli geçiş destekler</td>
      <td>Sınırlı</td>
    </tr>
  </tbody>
</table>

<h2 id="tip-güvenliğinin-teorik-anlamı">Tip güvenliğinin teorik anlamı</h2>

<p>Bir tip, olası değerler kümesi olarak düşünülebilir. Örneğin <code class="language-plaintext highlighter-rouge">number</code> tipi $N$ değer kümesini, <code class="language-plaintext highlighter-rouge">string</code> tipi ise $S$ kümesini temsil etsin. Bir fonksiyonun imzası şöyle modellenebilir:</p>

\[f: N \rightarrow N\]

<p>Bu ifade, fonksiyonun sayı kabul edip sayı ürettiğini söyler. Fonksiyona $x \in S$ verilmesi, tanımlanan sözleşmenin ihlalidir. TypeScript derleyicisi bu ihlali program çalışmadan yakalamaya çalışır.</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">double</span><span class="p">(</span><span class="nx">input</span><span class="p">:</span> <span class="kr">number</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span>
  <span class="k">return</span> <span class="nx">input</span> <span class="o">*</span> <span class="mi">2</span><span class="p">;</span>
<span class="p">}</span>

<span class="nf">double</span><span class="p">(</span><span class="mi">21</span><span class="p">);</span>     <span class="c1">// 42</span>
<span class="nf">double</span><span class="p">(</span><span class="dl">"</span><span class="s2">21</span><span class="dl">"</span><span class="p">);</span>   <span class="c1">// Derleme hatası</span>
</code></pre></div></div>

<p>Bu garanti mutlak değildir. Ağdan gelen JSON, kullanıcı girdisi veya yanlış kullanılan <code class="language-plaintext highlighter-rouge">any</code>, derleyicinin bilgisini aşabilir. Dolayısıyla TypeScript’in güvenliği, yalnızca ispatlayabildiği sınırlar içinde geçerlidir.</p>

<h2 id="yapısal-tipleme-i̇sim-değil-biçim-önemlidir">Yapısal tipleme: İsim değil, biçim önemlidir</h2>

<p>C++ çoğunlukla bildirilen tip kimliğine önem verirken TypeScript yapısal tipleme kullanır. Bir nesne gerekli alanlara sahipse ilgili tipe uyumlu kabul edilir. Bu yaklaşım JavaScript’in ördek tipleme geleneğiyle uyumludur: Ördek gibi görünüyorsa ve yüzüyorsa, büyük olasılıkla ördektir.</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">User</span> <span class="p">{</span>
  <span class="nl">id</span><span class="p">:</span> <span class="kr">number</span><span class="p">;</span>
  <span class="nl">name</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">customer</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">id</span><span class="p">:</span> <span class="mi">7</span><span class="p">,</span>
  <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Ada</span><span class="dl">"</span><span class="p">,</span>
  <span class="na">premium</span><span class="p">:</span> <span class="kc">true</span>
<span class="p">};</span>

<span class="kd">function</span> <span class="nf">greet</span><span class="p">(</span><span class="nx">user</span><span class="p">:</span> <span class="nx">User</span><span class="p">):</span> <span class="kr">string</span> <span class="p">{</span>
  <span class="k">return</span> <span class="s2">`Merhaba </span><span class="p">${</span><span class="nx">user</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2">`</span><span class="p">;</span>
<span class="p">}</span>

<span class="nf">greet</span><span class="p">(</span><span class="nx">customer</span><span class="p">);</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">customer</code>, açıkça <code class="language-plaintext highlighter-rouge">User</code> olarak tanımlanmamasına rağmen gerekli yapıyı taşır. Böylece katı güvenlik ile JavaScript’in nesne esnekliği arasında kullanışlı bir denge kurulur.</p>

<h2 id="tip-çıkarımı-ve-daraltma">Tip çıkarımı ve daraltma</h2>

<p>TypeScript her değişkene açıklama yazılmasını istemez. <code class="language-plaintext highlighter-rouge">const score = 100</code> ifadesinden tipin <code class="language-plaintext highlighter-rouge">number</code> olduğunu çıkarabilir. Birleşim tiplerinde ise kontrol akışını analiz ederek olasılıkları daraltır:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">format</span><span class="p">(</span><span class="nx">value</span><span class="p">:</span> <span class="kr">string</span> <span class="o">|</span> <span class="kr">number</span><span class="p">):</span> <span class="kr">string</span> <span class="p">{</span>
  <span class="k">if </span><span class="p">(</span><span class="k">typeof</span> <span class="nx">value</span> <span class="o">===</span> <span class="dl">"</span><span class="s2">number</span><span class="dl">"</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">value</span><span class="p">.</span><span class="nf">toFixed</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span>
  <span class="p">}</span>

  <span class="k">return</span> <span class="nx">value</span><span class="p">.</span><span class="nf">trim</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Bu davranış, tip sistemini yalnızca yasak koyan bir bekçi olmaktan çıkarıp kodu anlayan bir asistana dönüştürür. Editör otomatik tamamlama sunar, yeniden adlandırma işlemleri güvenilirleşir ve API sözleşmeleri belgelenebilir hâle gelir.</p>

<p>Sonuç olarak TypeScript, JavaScript’e C++ kostümü giydirmez. Bellek modeli, çalışma ortamı ve dinamik nesne yapısı hâlâ JavaScript’e aittir. TypeScript’in yaptığı şey, esnek bir dilin üzerine derleme zamanlı bir mantık ağı sermektir. Bu ağ tüm hataları yakalayamaz; fakat büyük projelerde yanlış varsayımları erkenden göstererek hata maliyetini ciddi ölçüde azaltır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="TypeScript" /><category term="JavaScript" /><category term="Statik Tipler" /><summary type="html"><![CDATA[JavaScript, geliştiriciye büyük bir hareket özgürlüğü sunar; ancak bu özgürlük bazen üretim ortamında patlayan küçük sürpriz paketlerine dönüşebilir. TypeScript’in temel felsefesi, JavaScript’in esnekliğini ortadan kaldırmak değil, program çalışmadan önce olası hataları görünür hâle getiren bir düşünme katmanı eklemektir. C ve C++ dünyasındaki statik tip denetimini anımsatan bu yaklaşım, dinamik web ekosistemine daha güvenli ve ölçeklenebilir bir geliştirme modeli kazandırır.]]></summary></entry><entry><title type="html">TypeScript Kurulumu ve VS Code ile Çalışma Ortamı Hazırlama</title><link href="https://sonsuzus.github.io/posts/typescript-kurulumu-ve-vs-code-ile-calisma-ortami-hazirlama/" rel="alternate" type="text/html" title="TypeScript Kurulumu ve VS Code ile Çalışma Ortamı Hazırlama" /><published>2026-08-04T00:00:00+00:00</published><updated>2026-08-04T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/typescript-kurulumu-ve-vs-code-ile-calisma-ortami-hazirlama</id><content type="html" xml:base="https://sonsuzus.github.io/posts/typescript-kurulumu-ve-vs-code-ile-calisma-ortami-hazirlama/"><![CDATA[<p>JavaScript projelerine tür güvenliği, daha güçlü editör desteği ve erken hata yakalama yeteneği kazandırmak istiyorsanız TypeScript harika bir başlangıç noktasıdır. Bu rehberde TypeScript derleyicisini Node.js üzerinden kuracak, temel yapılandırmayı gerçekleştirecek ve hazırladığımız çalışma ortamını VS Code içinde küçük bir örnekle sınayacağız.</p>

<p>``</p>

<h2 id="typescript-aslında-ne-yapar">TypeScript Aslında Ne Yapar?</h2>

<p>TypeScript, JavaScript’in üzerine statik tür sistemi ekleyen bir programlama dilidir. Tarayıcılar ve Node.js, TypeScript kodunu doğrudan çalıştırmaz. Bu nedenle <code class="language-plaintext highlighter-rouge">.ts</code> uzantılı dosyalar, TypeScript derleyicisi anlamına gelen <code class="language-plaintext highlighter-rouge">tsc</code> tarafından JavaScript’e dönüştürülür.</p>

<p>Bu dönüşümü basitçe şöyle gösterebiliriz:</p>

\[TypeScript\ Kaynak\ Kodu \xrightarrow{tsc} JavaScript\ Çıktısı\]

<p>Derleme sırasında türler kontrol edilir ve daha sonra silinir. Başka bir ifadeyle TypeScript’in tür sistemi geliştirme zamanında çalışır; ortaya çıkan JavaScript dosyasında tür açıklamaları bulunmaz.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>JavaScript</th>
      <th>TypeScript</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Tür kontrolü</td>
      <td>Çalışma zamanında ağırlıklı</td>
      <td>Derleme zamanında</td>
    </tr>
    <tr>
      <td>Dosya uzantısı</td>
      <td><code class="language-plaintext highlighter-rouge">.js</code></td>
      <td><code class="language-plaintext highlighter-rouge">.ts</code></td>
    </tr>
    <tr>
      <td>Tarayıcıda doğrudan çalışma</td>
      <td>Evet</td>
      <td>Hayır</td>
    </tr>
    <tr>
      <td>Editör desteği</td>
      <td>İyi</td>
      <td>Çok güçlü</td>
    </tr>
    <tr>
      <td>Derleme gereksinimi</td>
      <td>Genellikle yok</td>
      <td>Var</td>
    </tr>
  </tbody>
</table>

<p>Teorik olarak bir fonksiyonun beklediği tür $T$, gönderilen değerin türü $G$ olsun. Güvenli bir çağrı için temel beklenti $G \subseteq T$ biçiminde düşünülebilir. Uyumsuzluk varsa derleyici henüz programı çalıştırmadan bizi uyarır.</p>

<h2 id="nodejs-ve-proje-kurulumu">Node.js ve Proje Kurulumu</h2>

<p>Öncelikle Node.js’in güncel LTS sürümünü resmi sitesinden kurun. Kurulumla birlikte paket yöneticisi <code class="language-plaintext highlighter-rouge">npm</code> de bilgisayarınıza gelir. Terminalde doğrulama yapabilirsiniz:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>node <span class="nt">--version</span>
npm <span class="nt">--version</span>
</code></pre></div></div>

<p>Ardından proje klasörünü oluşturup bir Node.js projesi başlatalım:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir </span>typescript-baslangic
<span class="nb">cd </span>typescript-baslangic
npm init <span class="nt">-y</span>
npm <span class="nb">install</span> <span class="nt">--save-dev</span> typescript
</code></pre></div></div>

<p>Burada TypeScript’i global olarak değil, projeye özel bir geliştirme bağımlılığı şeklinde kurduk. Böylece farklı projeler farklı derleyici sürümlerini kullanabilir. Kurulumu doğrulamak için şu komutu çalıştırın:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npx tsc <span class="nt">--version</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">npx</code>, projenin <code class="language-plaintext highlighter-rouge">node_modules</code> klasöründeki yerel TypeScript derleyicisini bulup çalıştırır.</p>

<h2 id="tsconfigjson-yapılandırması">tsconfig.json Yapılandırması</h2>

<p>TypeScript yapılandırma dosyasını otomatik oluşturabiliriz:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npx tsc <span class="nt">--init</span>
</code></pre></div></div>

<p>Başlangıç için dosyayı daha sade bir içerikle düzenleyelim:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"compilerOptions"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"target"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ES2022"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"module"</span><span class="p">:</span><span class="w"> </span><span class="s2">"CommonJS"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"rootDir"</span><span class="p">:</span><span class="w"> </span><span class="s2">"src"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"outDir"</span><span class="p">:</span><span class="w"> </span><span class="s2">"dist"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"strict"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
    </span><span class="nl">"esModuleInterop"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
  </span><span class="p">},</span><span class="w">
  </span><span class="nl">"include"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"src/**/*.ts"</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">rootDir</code>, kaynak kodların yerini; <code class="language-plaintext highlighter-rouge">outDir</code> ise üretilen JavaScript dosyalarının hedefini belirtir. <code class="language-plaintext highlighter-rouge">strict</code>, daha kapsamlı tür denetimlerini etkinleştirir. <code class="language-plaintext highlighter-rouge">target</code> seçeneği de üretilecek JavaScript’in dil seviyesini belirler.</p>

<h2 id="vs-code-ortamını-hazırlama">VS Code Ortamını Hazırlama</h2>

<p>Proje klasörünü VS Code ile açın:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>code <span class="nb">.</span>
</code></pre></div></div>

<p>VS Code, TypeScript desteğini yerleşik olarak sunar. İsterseniz ESLint ve Prettier eklentilerini de kurarak kod kalitesi ile biçimlendirmeyi otomatikleştirebilirsiniz. Şimdi <code class="language-plaintext highlighter-rouge">src/index.ts</code> dosyasını oluşturalım:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">Kullanici</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">ad</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span>
  <span class="nl">puan</span><span class="p">:</span> <span class="kr">number</span><span class="p">;</span>
<span class="p">};</span>

<span class="kd">function</span> <span class="nf">seviyeHesapla</span><span class="p">(</span><span class="nx">kullanici</span><span class="p">:</span> <span class="nx">Kullanici</span><span class="p">):</span> <span class="kr">string</span> <span class="p">{</span>
  <span class="k">return</span> <span class="nx">kullanici</span><span class="p">.</span><span class="nx">puan</span> <span class="o">&gt;=</span> <span class="mi">100</span> <span class="p">?</span> <span class="dl">"</span><span class="s2">Usta</span><span class="dl">"</span> <span class="p">:</span> <span class="dl">"</span><span class="s2">Çırak</span><span class="dl">"</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">yazilimci</span><span class="p">:</span> <span class="nx">Kullanici</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">ad</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Ada</span><span class="dl">"</span><span class="p">,</span>
  <span class="na">puan</span><span class="p">:</span> <span class="mi">120</span>
<span class="p">};</span>

<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">`</span><span class="p">${</span><span class="nx">yazilimci</span><span class="p">.</span><span class="nx">ad</span><span class="p">}</span><span class="s2">: </span><span class="p">${</span><span class="nf">seviyeHesapla</span><span class="p">(</span><span class="nx">yazilimci</span><span class="p">)}</span><span class="s2">`</span><span class="p">);</span>
</code></pre></div></div>

<p>Bu örnekte <code class="language-plaintext highlighter-rouge">Kullanici</code> türü nesnenin sözleşmesini tanımlar. <code class="language-plaintext highlighter-rouge">puan</code> alanına yanlışlıkla metin verirseniz VS Code, daha derleme yapmadan kırmızı bir uyarı gösterecektir.</p>

<p>Projeyi derleyip çalıştırmak için:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npx tsc
node dist/index.js
</code></pre></div></div>

<p>Terminalde <code class="language-plaintext highlighter-rouge">Ada: Usta</code> çıktısını görüyorsanız zincirin tamamı çalışıyor demektir: VS Code kodu analiz etti, <code class="language-plaintext highlighter-rouge">tsc</code> türleri denetleyip JavaScript üretti ve Node.js sonucu çalıştırdı. Artık daha büyük TypeScript maceralarına hazırsınız!</p>]]></content><author><name>Sonsuz Us</name></author><category term="Program" /><category term="TypeScript" /><category term="Node.js" /><category term="VS Code" /><summary type="html"><![CDATA[JavaScript projelerine tür güvenliği, daha güçlü editör desteği ve erken hata yakalama yeteneği kazandırmak istiyorsanız TypeScript harika bir başlangıç noktasıdır. Bu rehberde TypeScript derleyicisini Node.js üzerinden kuracak, temel yapılandırmayı gerçekleştirecek ve hazırladığımız çalışma ortamını VS Code içinde küçük bir örnekle sınayacağız.]]></summary></entry><entry><title type="html">TypeScript Tip Takma Adları: Karmaşık Tipleri Okunabilir Hale Getirmek</title><link href="https://sonsuzus.github.io/posts/typescript-tip-takma-adlari-karmasik-tipleri-okunabilir-hale-getirmek/" rel="alternate" type="text/html" title="TypeScript Tip Takma Adları: Karmaşık Tipleri Okunabilir Hale Getirmek" /><published>2026-08-04T00:00:00+00:00</published><updated>2026-08-04T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/typescript-tip-takma-adlari-karmasik-tipleri-okunabilir-hale-getirmek</id><content type="html" xml:base="https://sonsuzus.github.io/posts/typescript-tip-takma-adlari-karmasik-tipleri-okunabilir-hale-getirmek/"><![CDATA[<p>Bir projede aynı uzun tip tanımını üçüncü kez yazarken parmaklarınız “Bunun daha kısa bir yolu olmalı!” diye isyan ediyorsa, TypeScript’in <strong>tip takma adları</strong> yardımınıza yetişir. Type alias, karmaşık veya sık kullanılan bir tipe anlamlı bir isim vererek kodun okunabilirliğini artırır; üstelik bunu çalışma zamanına ek yük getirmeden yapar.
``</p>
<h2 id="type-alias-nedir">Type alias nedir?</h2>

<p>TypeScript’te <code class="language-plaintext highlighter-rouge">type</code> anahtar sözcüğü, mevcut bir tip ifadesine yeni bir ad verir. En basit örnekle başlayalım:</p>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">UserId</span> <span class="o">=</span> <span class="kr">string</span><span class="p">;</span>

<span class="kd">const</span> <span class="nx">activeUserId</span><span class="p">:</span> <span class="nx">UserId</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">usr_42</span><span class="dl">"</span><span class="p">;</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">UserId</code>, teknik olarak hâlâ <code class="language-plaintext highlighter-rouge">string</code> tipidir. Ancak değişkenin sıradan bir metin değil, kullanıcı kimliği taşıdığı artık çok daha açıktır. Type alias yeni bir çalışma zamanı değeri veya sınıf üretmez; yalnızca derleme aşamasında kullanılır ve JavaScript çıktısından silinir.</p>

<p>Bunu matematiksel olarak $A = B$ biçiminde düşünebiliriz: <code class="language-plaintext highlighter-rouge">UserId</code> ile <code class="language-plaintext highlighter-rouge">string</code> farklı adlara sahip olsa da aynı değer kümesini temsil eder. Dolayısıyla TypeScript’in yapısal tip sisteminde her <code class="language-plaintext highlighter-rouge">string</code>, aksi yönde özel bir marka oluşturulmadıkça <code class="language-plaintext highlighter-rouge">UserId</code> olarak kabul edilebilir.</p>

<h2 id="karmaşık-nesneleri-sadeleştirmek">Karmaşık nesneleri sadeleştirmek</h2>

<p>Takma adların asıl gücü, iç içe geçmiş nesne tiplerinde ortaya çıkar:</p>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">Address</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">city</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span>
  <span class="nl">district</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span>
  <span class="nl">postalCode</span><span class="p">?:</span> <span class="kr">string</span><span class="p">;</span>
<span class="p">};</span>

<span class="kd">type</span> <span class="nx">User</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">id</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span>
  <span class="nl">name</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span>
  <span class="nl">address</span><span class="p">:</span> <span class="nx">Address</span><span class="p">;</span>
<span class="p">};</span>

<span class="kd">function</span> <span class="nf">printUser</span><span class="p">(</span><span class="nx">user</span><span class="p">:</span> <span class="nx">User</span><span class="p">):</span> <span class="k">void</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">`</span><span class="p">${</span><span class="nx">user</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2"> - </span><span class="p">${</span><span class="nx">user</span><span class="p">.</span><span class="nx">address</span><span class="p">.</span><span class="nx">city</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">Address</code> ayrı bir kavram olarak tanımlandığı için hem tekrar önlenir hem de <code class="language-plaintext highlighter-rouge">User</code> tipi daha kolay okunur. Adres yapısı değiştiğinde onlarca fonksiyon imzasını düzenlemek yerine tek bir merkezi tanım güncellenir.</p>

<table>
  <thead>
    <tr>
      <th>Doğrudan tip yazımı</th>
      <th>Type alias kullanımı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Tekrar üretir</td>
      <td>Tekrarı azaltır</td>
    </tr>
    <tr>
      <td>Fonksiyon imzalarını uzatır</td>
      <td>İmzaları sadeleştirir</td>
    </tr>
    <tr>
      <td>Değişiklikleri zorlaştırır</td>
      <td>Merkezi güncelleme sağlar</td>
    </tr>
    <tr>
      <td>Alanın amacını gizleyebilir</td>
      <td>İş alanını görünür kılar</td>
    </tr>
  </tbody>
</table>

<h2 id="birleşim-ve-kesişim-tipleri">Birleşim ve kesişim tipleri</h2>

<p>Type alias yalnızca nesnelere isim vermek için kullanılmaz. Birleşim, kesişim, tuple ve fonksiyon tipleri de adlandırılabilir:</p>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">RequestStatus</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">idle</span><span class="dl">"</span> <span class="o">|</span> <span class="dl">"</span><span class="s2">loading</span><span class="dl">"</span> <span class="o">|</span> <span class="dl">"</span><span class="s2">success</span><span class="dl">"</span> <span class="o">|</span> <span class="dl">"</span><span class="s2">error</span><span class="dl">"</span><span class="p">;</span>
<span class="kd">type</span> <span class="nx">Coordinates</span> <span class="o">=</span> <span class="p">[</span><span class="nx">latitude</span><span class="p">:</span> <span class="kr">number</span><span class="p">,</span> <span class="nx">longitude</span><span class="p">:</span> <span class="kr">number</span><span class="p">];</span>
<span class="kd">type</span> <span class="nx">Logger</span> <span class="o">=</span> <span class="p">(</span><span class="nx">message</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="nx">level</span><span class="p">?:</span> <span class="dl">"</span><span class="s2">info</span><span class="dl">"</span> <span class="o">|</span> <span class="dl">"</span><span class="s2">warn</span><span class="dl">"</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="k">void</span><span class="p">;</span>

<span class="kd">type</span> <span class="nx">Timestamped</span> <span class="o">=</span> <span class="p">{</span> <span class="na">createdAt</span><span class="p">:</span> <span class="nb">Date</span> <span class="p">};</span>
<span class="kd">type</span> <span class="nx">Product</span> <span class="o">=</span> <span class="p">{</span> <span class="na">id</span><span class="p">:</span> <span class="kr">number</span><span class="p">;</span> <span class="nl">name</span><span class="p">:</span> <span class="kr">string</span> <span class="p">};</span>
<span class="kd">type</span> <span class="nx">StoredProduct</span> <span class="o">=</span> <span class="nx">Product</span> <span class="o">&amp;</span> <span class="nx">Timestamped</span><span class="p">;</span>
</code></pre></div></div>

<p>Birleşim tipi $T = A \cup B$ yaklaşımıyla, değerin izin verilen kümelerden birine ait olmasını sağlar. <code class="language-plaintext highlighter-rouge">RequestStatus</code> örneğinde rastgele bir metin yerine yalnızca dört durum kabul edilir. Kesişim tipi $T = A \cap B$ ise bir değerin iki tipin özelliklerini birlikte taşımasını ister.</p>

<h2 id="generic-takma-adlarla-yeniden-kullanılabilirlik">Generic takma adlarla yeniden kullanılabilirlik</h2>

<p>Generic yapılar, farklı veri tipleri için aynı şablonu kullanmamızı sağlar:</p>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">ApiResponse</span><span class="o">&lt;</span><span class="nx">T</span><span class="o">&gt;</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">data</span><span class="p">:</span> <span class="nx">T</span> <span class="o">|</span> <span class="kc">null</span><span class="p">;</span>
  <span class="nl">error</span><span class="p">:</span> <span class="kr">string</span> <span class="o">|</span> <span class="kc">null</span><span class="p">;</span>
  <span class="nl">statusCode</span><span class="p">:</span> <span class="kr">number</span><span class="p">;</span>
<span class="p">};</span>

<span class="kd">type</span> <span class="nx">UserResponse</span> <span class="o">=</span> <span class="nx">ApiResponse</span><span class="o">&lt;</span><span class="nx">User</span><span class="o">&gt;</span><span class="p">;</span>
</code></pre></div></div>

<p>Buradaki <code class="language-plaintext highlighter-rouge">T</code>, daha sonra yerleştirilecek tip için parametredir. Böylece kullanıcı, ürün veya sipariş yanıtlarında aynı API yapısını tekrar yazmak gerekmez. Bir yapının $n$ farklı veri modeli için kullanıldığını düşünürsek, tekrar miktarı yaklaşık $n \times k$ satırdan tek bir <code class="language-plaintext highlighter-rouge">k</code> satırlık şablona indirilebilir.</p>

<h2 id="type-alias-mı-interface-mi">Type alias mı, interface mi?</h2>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th><code class="language-plaintext highlighter-rouge">type</code></th>
      <th><code class="language-plaintext highlighter-rouge">interface</code></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Nesne tanımlama</td>
      <td>Evet</td>
      <td>Evet</td>
    </tr>
    <tr>
      <td>Union ve tuple</td>
      <td>Evet</td>
      <td>Hayır</td>
    </tr>
    <tr>
      <td>Declaration merging</td>
      <td>Hayır</td>
      <td>Evet</td>
    </tr>
    <tr>
      <td>Genişletme</td>
      <td>Kesişim ile</td>
      <td><code class="language-plaintext highlighter-rouge">extends</code> ile</td>
    </tr>
    <tr>
      <td>Primitive tipe ad verme</td>
      <td>Evet</td>
      <td>Hayır</td>
    </tr>
  </tbody>
</table>

<p>Nesne odaklı ve sonradan genişletilecek genel API sözleşmelerinde <code class="language-plaintext highlighter-rouge">interface</code>; union, tuple, fonksiyon veya birleşik tiplerde <code class="language-plaintext highlighter-rouge">type</code> genellikle daha uygundur. Bu kesin bir savaş değil, doğru aleti seçme meselesidir.</p>

<p>Son olarak takma adları <code class="language-plaintext highlighter-rouge">Data</code>, <code class="language-plaintext highlighter-rouge">Info</code> veya <code class="language-plaintext highlighter-rouge">Thing</code> gibi belirsiz isimlerle doldurmayın. <code class="language-plaintext highlighter-rouge">CheckoutResult</code>, <code class="language-plaintext highlighter-rouge">AuthenticatedUser</code> ve <code class="language-plaintext highlighter-rouge">ProductFilter</code> gibi niyeti anlatan adlar seçin. İyi bir type alias kodu yalnızca kısaltmaz; geliştiriciye sistemin iş kurallarını sessizce anlatan küçük bir belgeye dönüşür.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="TypeScript" /><category term="Type Aliases" /><category term="Tip Güvenliği" /><summary type="html"><![CDATA[Bir projede aynı uzun tip tanımını üçüncü kez yazarken parmaklarınız “Bunun daha kısa bir yolu olmalı!” diye isyan ediyorsa, TypeScript’in tip takma adları yardımınıza yetişir. Type alias, karmaşık veya sık kullanılan bir tipe anlamlı bir isim vererek kodun okunabilirliğini artırır; üstelik bunu çalışma zamanına ek yük getirmeden yapar.]]></summary></entry><entry><title type="html">TypeScript’te any ve unknown: Esneklik mi, Tip Güvenliği mi?</title><link href="https://sonsuzus.github.io/posts/typescriptte-any-ve-unknown-esneklik-mi-tip-guvenligi-mi/" rel="alternate" type="text/html" title="TypeScript’te any ve unknown: Esneklik mi, Tip Güvenliği mi?" /><published>2026-08-04T00:00:00+00:00</published><updated>2026-08-04T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/typescriptte-any-ve-unknown-esneklik-mi-tip-guvenligi-mi</id><content type="html" xml:base="https://sonsuzus.github.io/posts/typescriptte-any-ve-unknown-esneklik-mi-tip-guvenligi-mi/"><![CDATA[<p>TypeScript kullanırken bazen elimizdeki değerin tipini gerçekten bilemeyiz. Bir API cevabı, kullanıcı girdisi veya eski bir JavaScript kütüphanesi her şeyi döndürebilir. İşte bu belirsizlik karşısında <code class="language-plaintext highlighter-rouge">any</code> ve <code class="language-plaintext highlighter-rouge">unknown</code> sahneye çıkar. İkisi de “Bu değerin tipi şimdilik belli değil” diyebilir; ancak biri güvenlik kapısını açık bırakırken diğeri kimlik kontrolü yapmadan kimseyi içeri almaz.
``</p>
<h2 id="any-typescripte-kısa-bir-mola-verdirmek"><code class="language-plaintext highlighter-rouge">any</code>: TypeScript’e kısa bir mola verdirmek</h2>

<p><code class="language-plaintext highlighter-rouge">any</code>, TypeScript’in tip denetimini ilgili değer için büyük ölçüde kapatır. <code class="language-plaintext highlighter-rouge">any</code> tipindeki bir değişkene her tür değer atanabilir ve bu değişken üzerinde neredeyse her işlem gerçekleştirilebilir.</p>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">let</span> <span class="nx">veri</span><span class="p">:</span> <span class="kr">any</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">TypeScript</span><span class="dl">"</span><span class="p">;</span>

<span class="nx">veri</span><span class="p">.</span><span class="nf">toUpperCase</span><span class="p">();</span> <span class="c1">// Çalışabilir</span>
<span class="nx">veri</span> <span class="o">=</span> <span class="mi">42</span><span class="p">;</span>
<span class="nx">veri</span><span class="p">.</span><span class="nf">toFixed</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span>    <span class="c1">// Bu da çalışabilir</span>
<span class="nx">veri</span><span class="p">.</span><span class="nf">olmayANMetot</span><span class="p">();</span> <span class="c1">// Derleyici itiraz etmez!</span>
</code></pre></div></div>

<p>Son satır TypeScript tarafından kabul edilir; fakat çalışma zamanında büyük olasılıkla <code class="language-plaintext highlighter-rouge">TypeError</code> oluşur. Yani <code class="language-plaintext highlighter-rouge">any</code>, JavaScript’in eski ve özgür dünyasına geçici bir dönüş bileti gibidir. Bilet eğlencelidir, fakat emniyet kemeri yanında verilmez.</p>

<p>Teorik olarak <code class="language-plaintext highlighter-rouge">any</code>, tip sistemi içinde hem üst hem alt tip gibi davranabilen özel bir kaçış mekanizmasıdır. Basitleştirilmiş biçimde, herhangi bir $T$ tipi için şu esneklik düşünülebilir:</p>

\[any \rightarrow T \quad ve \quad T \rightarrow any\]

<p>Bu çift yönlü geçiş, tip denetiminin sağladığı garantileri zayıflatır. Dolayısıyla <code class="language-plaintext highlighter-rouge">any</code>, bilinçli ve sınırlı kullanılmalıdır.</p>

<h2 id="unknown-önce-kontrol-sonra-hareket"><code class="language-plaintext highlighter-rouge">unknown</code>: Önce kontrol, sonra hareket</h2>

<p><code class="language-plaintext highlighter-rouge">unknown</code> da her tür değeri kabul eder. Fakat değeri kullanmadan önce tipini daraltmamızı, yani <strong>type narrowing</strong> yapmamızı zorunlu kılar.</p>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">let</span> <span class="nx">cevap</span><span class="p">:</span> <span class="nx">unknown</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">Merhaba dünya</span><span class="dl">"</span><span class="p">;</span>

<span class="c1">// cevap.toUpperCase(); // Hata: Tip henüz bilinmiyor</span>

<span class="k">if </span><span class="p">(</span><span class="k">typeof</span> <span class="nx">cevap</span> <span class="o">===</span> <span class="dl">"</span><span class="s2">string</span><span class="dl">"</span><span class="p">)</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">cevap</span><span class="p">.</span><span class="nf">toUpperCase</span><span class="p">());</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">typeof</code> kontrolünden sonra TypeScript, <code class="language-plaintext highlighter-rouge">cevap</code> değişkeninin ilgili blok içinde <code class="language-plaintext highlighter-rouge">string</code> olduğunu bilir. Bu yaklaşımın mantığı şöyledir:</p>

\[unknown + tip\ kontrolü = güvenli\ T\]

<p>Başka bir ifadeyle <code class="language-plaintext highlighter-rouge">unknown</code>, belirsizliği saklamaz; onu çözme sorumluluğunu programcıya açıkça verir.</p>

<h2 id="temel-farklar">Temel farklar</h2>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th><code class="language-plaintext highlighter-rouge">any</code></th>
      <th><code class="language-plaintext highlighter-rouge">unknown</code></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Her tür değer atanabilir mi?</td>
      <td>Evet</td>
      <td>Evet</td>
    </tr>
    <tr>
      <td>Doğrudan metot çağrılabilir mi?</td>
      <td>Evet</td>
      <td>Hayır</td>
    </tr>
    <tr>
      <td>Tip kontrolü zorunlu mu?</td>
      <td>Hayır</td>
      <td>Evet</td>
    </tr>
    <tr>
      <td>Çalışma zamanı hatası riski</td>
      <td>Yüksek</td>
      <td>Daha düşük</td>
    </tr>
    <tr>
      <td>Tip güvenliğini korur mu?</td>
      <td>Hayır</td>
      <td>Evet</td>
    </tr>
    <tr>
      <td>Hızlı geçiş ve eski kod uyumu</td>
      <td>Çok uygun</td>
      <td>Daha kontrollü</td>
    </tr>
  </tbody>
</table>

<h2 id="gerçek-dünyada-güvenli-veri-işleme">Gerçek dünyada güvenli veri işleme</h2>

<p>Dış kaynaklardan gelen JSON verileri, <code class="language-plaintext highlighter-rouge">unknown</code> için ideal bir kullanım alanıdır. Çünkü sunucunun sözleşmeye her zaman uyacağını varsaymak risklidir.</p>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">Kullanici</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">ad</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span>
  <span class="nl">yas</span><span class="p">:</span> <span class="kr">number</span><span class="p">;</span>
<span class="p">};</span>

<span class="kd">function</span> <span class="nf">kullaniciMi</span><span class="p">(</span><span class="nx">deger</span><span class="p">:</span> <span class="nx">unknown</span><span class="p">):</span> <span class="nx">deger</span> <span class="k">is</span> <span class="nx">Kullanici</span> <span class="p">{</span>
  <span class="k">if </span><span class="p">(</span><span class="k">typeof</span> <span class="nx">deger</span> <span class="o">!==</span> <span class="dl">"</span><span class="s2">object</span><span class="dl">"</span> <span class="o">||</span> <span class="nx">deger</span> <span class="o">===</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
  <span class="p">}</span>

  <span class="kd">const</span> <span class="nx">aday</span> <span class="o">=</span> <span class="nx">deger</span> <span class="kd">as </span><span class="nb">Record</span><span class="o">&lt;</span><span class="kr">string</span><span class="p">,</span> <span class="nx">unknown</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="k">return</span> <span class="k">typeof</span> <span class="nx">aday</span><span class="p">.</span><span class="nx">ad</span> <span class="o">===</span> <span class="dl">"</span><span class="s2">string</span><span class="dl">"</span> <span class="o">&amp;&amp;</span>
         <span class="k">typeof</span> <span class="nx">aday</span><span class="p">.</span><span class="nx">yas</span> <span class="o">===</span> <span class="dl">"</span><span class="s2">number</span><span class="dl">"</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">hamVeri</span><span class="p">:</span> <span class="nx">unknown</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="dl">'</span><span class="s1">{"ad":"Ada","yas":28}</span><span class="dl">'</span><span class="p">);</span>

<span class="k">if </span><span class="p">(</span><span class="nf">kullaniciMi</span><span class="p">(</span><span class="nx">hamVeri</span><span class="p">))</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">`</span><span class="p">${</span><span class="nx">hamVeri</span><span class="p">.</span><span class="nx">ad</span><span class="p">}</span><span class="s2">, </span><span class="p">${</span><span class="nx">hamVeri</span><span class="p">.</span><span class="nx">yas</span><span class="p">}</span><span class="s2"> yaşında.`</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">kullaniciMi</code> fonksiyonu bir <strong>type guard</strong> oluşturur. Yalnızca nesne yapısı doğrulandığında veriye <code class="language-plaintext highlighter-rouge">Kullanici</code> gibi davranılır. Böylece API’den gelen sürpriz bir dizi, <code class="language-plaintext highlighter-rouge">null</code> veya eksik alanlı nesne uygulamayı kolayca sabote edemez.</p>

<h2 id="hangisini-seçmeliyiz">Hangisini seçmeliyiz?</h2>

<p>Yeni kod yazarken varsayılan tercih <code class="language-plaintext highlighter-rouge">unknown</code> olmalıdır. <code class="language-plaintext highlighter-rouge">any</code>; tip tanımı bulunmayan eski kütüphaneleri bağlamak, aşamalı JavaScript dönüşümü yapmak veya kısa süreli prototip geliştirmek için kullanılabilir. Yine de mümkün olan en küçük alana hapsedilmelidir.</p>

<p>Kısacası <code class="language-plaintext highlighter-rouge">any</code>, “Ne yaptığımı biliyorum, bana karışma” der. <code class="language-plaintext highlighter-rouge">unknown</code> ise “Önce kanıtla, sonra devam et” yaklaşımını benimser. Büyük ve uzun ömürlü projelerde ikinci cümle genellikle daha az hata, daha iyi otomatik tamamlama ve daha huzurlu geliştiriciler anlamına gelir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="TypeScript" /><category term="JavaScript" /><category term="Tip Güvenliği" /><summary type="html"><![CDATA[TypeScript kullanırken bazen elimizdeki değerin tipini gerçekten bilemeyiz. Bir API cevabı, kullanıcı girdisi veya eski bir JavaScript kütüphanesi her şeyi döndürebilir. İşte bu belirsizlik karşısında any ve unknown sahneye çıkar. İkisi de “Bu değerin tipi şimdilik belli değil” diyebilir; ancak biri güvenlik kapısını açık bırakırken diğeri kimlik kontrolü yapmadan kimseyi içeri almaz.]]></summary></entry><entry><title type="html">TypeScript’te Union ve Intersection Tipleri: Ya O, Ya Bu… Bazen de Hepsi!</title><link href="https://sonsuzus.github.io/posts/typescriptte-union-ve-intersection-tipleri-ya-o-ya-bu-bazen-de-hepsi/" rel="alternate" type="text/html" title="TypeScript’te Union ve Intersection Tipleri: Ya O, Ya Bu… Bazen de Hepsi!" /><published>2026-08-04T00:00:00+00:00</published><updated>2026-08-04T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/typescriptte-union-ve-intersection-tipleri-ya-o-ya-bu-bazen-de-hepsi</id><content type="html" xml:base="https://sonsuzus.github.io/posts/typescriptte-union-ve-intersection-tipleri-ya-o-ya-bu-bazen-de-hepsi/"><![CDATA[<p>TypeScript’in tip sistemi, değişkenleri tek bir kalıba hapsetmek yerine gerçek dünyadaki çeşitliliği modellememize yardımcı olur. Bir değerin alternatif tiplerden birini taşıyabildiği durumlarda <strong>union</strong>, farklı yapıların bütün özelliklerini aynı nesnede toplamak istediğimizde ise <strong>intersection</strong> tipleri devreye girer. İsimleri matematik dersini hatırlatsa da doğru kullanıldıklarında kodu hem güvenli hem de oldukça esnek hâle getirirler.
``</p>
<h2 id="union-tipi-bu-veya-şu">Union tipi: Bu veya şu</h2>

<p>Union, <code class="language-plaintext highlighter-rouge">|</code> operatörüyle oluşturulur ve bir değerin belirtilen tiplerden <strong>en az birine</strong> uygun olabileceğini anlatır. Matematiksel olarak iki tipin birleşimini şöyle gösterebiliriz:</p>

\[U = A \cup B\]

<p>Örneğin kullanıcı kimliği bazı sistemlerde sayı, bazılarında metin olabilir:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">Kimlik</span> <span class="o">=</span> <span class="kr">string</span> <span class="o">|</span> <span class="kr">number</span><span class="p">;</span>

<span class="kd">function</span> <span class="nf">kimlikYazdir</span><span class="p">(</span><span class="nx">kimlik</span><span class="p">:</span> <span class="nx">Kimlik</span><span class="p">):</span> <span class="k">void</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">`Kullanıcı kimliği: </span><span class="p">${</span><span class="nx">kimlik</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span>
<span class="p">}</span>

<span class="nf">kimlikYazdir</span><span class="p">(</span><span class="mi">42</span><span class="p">);</span>
<span class="nf">kimlikYazdir</span><span class="p">(</span><span class="dl">"</span><span class="s2">USR-42</span><span class="dl">"</span><span class="p">);</span>
</code></pre></div></div>

<p>Bu fonksiyon hem <code class="language-plaintext highlighter-rouge">number</code> hem de <code class="language-plaintext highlighter-rouge">string</code> kabul eder. Ancak TypeScript, değerin o anda hangi tipe ait olduğunu bilmeden tipe özel işlemler yapılmasına izin vermez. Örneğin doğrudan <code class="language-plaintext highlighter-rouge">kimlik.toUpperCase()</code> çağırmak hatalıdır; çünkü sayıların böyle bir metodu yoktur.</p>

<p>Çözüm, <strong>type narrowing</strong>, yani tip daraltmadır:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">kimlikBicimlendir</span><span class="p">(</span><span class="nx">kimlik</span><span class="p">:</span> <span class="kr">string</span> <span class="o">|</span> <span class="kr">number</span><span class="p">):</span> <span class="kr">string</span> <span class="p">{</span>
  <span class="k">if </span><span class="p">(</span><span class="k">typeof</span> <span class="nx">kimlik</span> <span class="o">===</span> <span class="dl">"</span><span class="s2">string</span><span class="dl">"</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">kimlik</span><span class="p">.</span><span class="nf">toUpperCase</span><span class="p">();</span>
  <span class="p">}</span>

  <span class="k">return</span> <span class="nx">kimlik</span><span class="p">.</span><span class="nf">toFixed</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">typeof</code> kontrolünden sonra TypeScript ilk dalda değerin <code class="language-plaintext highlighter-rouge">string</code>, diğer dalda ise <code class="language-plaintext highlighter-rouge">number</code> olduğunu anlar. Böylece esneklik uğruna tip güvenliğinden vazgeçilmez.</p>

<h2 id="intersection-tipi-hem-bu-hem-şu">Intersection tipi: Hem bu hem şu</h2>

<p>Intersection, <code class="language-plaintext highlighter-rouge">&amp;</code> operatörüyle tanımlanır. Oluşan tip, birleştirilen tiplerin <strong>bütün gereksinimlerini aynı anda</strong> karşılamalıdır:</p>

\[I = A \cap B\]

<p>Bir çalışanı hem kişi bilgileriyle hem de kurumsal yetkilerle modelleyelim:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">Kisi</span> <span class="p">{</span>
  <span class="nl">ad</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span>
  <span class="nl">yas</span><span class="p">:</span> <span class="kr">number</span><span class="p">;</span>
<span class="p">}</span>

<span class="kr">interface</span> <span class="nx">Calisan</span> <span class="p">{</span>
  <span class="nl">departman</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span>
  <span class="nl">yetkiSeviyesi</span><span class="p">:</span> <span class="kr">number</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">type</span> <span class="nx">KurumsalKullanici</span> <span class="o">=</span> <span class="nx">Kisi</span> <span class="o">&amp;</span> <span class="nx">Calisan</span><span class="p">;</span>

<span class="kd">const</span> <span class="nx">kullanici</span><span class="p">:</span> <span class="nx">KurumsalKullanici</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">ad</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Ada</span><span class="dl">"</span><span class="p">,</span>
  <span class="na">yas</span><span class="p">:</span> <span class="mi">28</span><span class="p">,</span>
  <span class="na">departman</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Yazılım</span><span class="dl">"</span><span class="p">,</span>
  <span class="na">yetkiSeviyesi</span><span class="p">:</span> <span class="mi">3</span>
<span class="p">};</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">KurumsalKullanici</code>, iki arayüzden yalnızca birini seçmez; ikisinin alanlarını da zorunlu tutar. <code class="language-plaintext highlighter-rouge">departman</code> veya <code class="language-plaintext highlighter-rouge">yas</code> kaldırılırsa derleyici itiraz eder. Intersection’ı, farklı LEGO setlerini aynı modelde kullanmak gibi düşünebiliriz: Parçaların hiçbiri kaybolmaz.</p>

<h2 id="temel-farklar">Temel farklar</h2>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Union (<code class="language-plaintext highlighter-rouge">A \| B</code>)</th>
      <th>Intersection (<code class="language-plaintext highlighter-rouge">A &amp; B</code>)</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Anlam</td>
      <td>A veya B</td>
      <td>Hem A hem B</td>
    </tr>
    <tr>
      <td>Amaç</td>
      <td>Alternatif değerleri modellemek</td>
      <td>Özellikleri tek yapıda toplamak</td>
    </tr>
    <tr>
      <td>Güvenli erişim</td>
      <td>Ortak üyeler kullanılabilir</td>
      <td>Tüm üyeler kullanılabilir</td>
    </tr>
    <tr>
      <td>Tip daraltma</td>
      <td>Genellikle gerekir</td>
      <td>Çoğunlukla gerekmez</td>
    </tr>
    <tr>
      <td>Yaygın kullanım</td>
      <td>API durumları, kimlikler, sonuçlar</td>
      <td>Rol, yetki ve nesne bileşimi</td>
    </tr>
  </tbody>
</table>

<h2 id="ayırt-edilebilir-union-modeli">Ayırt edilebilir union modeli</h2>

<p>Union tiplerinin en güçlü kullanım alanlarından biri, her seçeneğe sabit bir ayırt edici alan eklemektir:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">Sonuc</span> <span class="o">=</span>
  <span class="o">|</span> <span class="p">{</span> <span class="na">durum</span><span class="p">:</span> <span class="dl">"</span><span class="s2">basarili</span><span class="dl">"</span><span class="p">;</span> <span class="nl">veri</span><span class="p">:</span> <span class="kr">string</span><span class="p">[]</span> <span class="p">}</span>
  <span class="o">|</span> <span class="p">{</span> <span class="na">durum</span><span class="p">:</span> <span class="dl">"</span><span class="s2">hatali</span><span class="dl">"</span><span class="p">;</span> <span class="nl">mesaj</span><span class="p">:</span> <span class="kr">string</span> <span class="p">};</span>

<span class="kd">function</span> <span class="nf">sonucuGoster</span><span class="p">(</span><span class="nx">sonuc</span><span class="p">:</span> <span class="nx">Sonuc</span><span class="p">):</span> <span class="k">void</span> <span class="p">{</span>
  <span class="k">switch </span><span class="p">(</span><span class="nx">sonuc</span><span class="p">.</span><span class="nx">durum</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">case</span> <span class="dl">"</span><span class="s2">basarili</span><span class="dl">"</span><span class="p">:</span>
      <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">sonuc</span><span class="p">.</span><span class="nx">veri</span><span class="p">.</span><span class="nf">join</span><span class="p">(</span><span class="dl">"</span><span class="s2">, </span><span class="dl">"</span><span class="p">));</span>
      <span class="k">break</span><span class="p">;</span>
    <span class="k">case</span> <span class="dl">"</span><span class="s2">hatali</span><span class="dl">"</span><span class="p">:</span>
      <span class="nx">console</span><span class="p">.</span><span class="nf">error</span><span class="p">(</span><span class="nx">sonuc</span><span class="p">.</span><span class="nx">mesaj</span><span class="p">);</span>
      <span class="k">break</span><span class="p">;</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Buradaki <code class="language-plaintext highlighter-rouge">durum</code> alanı, union üyelerini ayırt eden etikettir. Başarılı sonuçta <code class="language-plaintext highlighter-rouge">veri</code>, hatalı sonuçta <code class="language-plaintext highlighter-rouge">mesaj</code> güvenle kullanılabilir. Bu yaklaşım API yanıtlarında ve durum makinelerinde sık görülür.</p>

<h2 id="tehlikeli-kesişimler">Tehlikeli kesişimler</h2>

<p>Her intersection mantıklı bir sonuç üretmez. Örneğin <code class="language-plaintext highlighter-rouge">string &amp; number</code>, aynı değerin eş zamanlı olarak hem metin hem sayı olmasını ister. Böyle bir değer üretilemeyeceği için sonuç pratikte <code class="language-plaintext highlighter-rouge">never</code> tipidir:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">Imkansiz</span> <span class="o">=</span> <span class="kr">string</span> <span class="o">&amp;</span> <span class="kr">number</span><span class="p">;</span> <span class="c1">// never</span>
</code></pre></div></div>

<p>Benzer şekilde, aynı isimli alanlar uyumsuz tiplerle kesiştirildiğinde ilgili alan kullanılamaz hâle gelebilir. Bu nedenle intersection oluştururken arayüzlerin çelişmediği kontrol edilmelidir.</p>

<p>Özetle union, “seçeneklerden biri”; intersection ise “gereksinimlerin tamamı” demektir. Alternatif akışları union ile, farklı yetenekleri taşıyan birleşik nesneleri intersection ile modellemek kodun niyetini görünür kılar. TypeScript de bu modelin dışına çıktığınız anda nazik ama kararlı bir bekçi gibi sizi uyarır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="TypeScript" /><category term="Union Types" /><category term="Intersection Types" /><summary type="html"><![CDATA[TypeScript’in tip sistemi, değişkenleri tek bir kalıba hapsetmek yerine gerçek dünyadaki çeşitliliği modellememize yardımcı olur. Bir değerin alternatif tiplerden birini taşıyabildiği durumlarda union, farklı yapıların bütün özelliklerini aynı nesnede toplamak istediğimizde ise intersection tipleri devreye girer. İsimleri matematik dersini hatırlatsa da doğru kullanıldıklarında kodu hem güvenli hem de oldukça esnek hâle getirirler.]]></summary></entry></feed>