← Blog
·10 blog.minutes

TypeScript Desenleri ve En Iyi Uygulamalar: 2026ya Dair

Bildirimsel tipler, tagged union lar, branded tipler, assertion fonksiyonlari ve modern TypeScript in yaptiginiz her kodu daha guvenilir hale getiren diger ozelliklerine dair kapsamli bir bakis.

TypeScript on yili askin bir suredir var ve bu surenin her yilinda tip sistemi daha guclu ve etkileyici hale geldi. Ancak guclu bir dil, ayni zamanda daha fazla sorumluluk getirir. Bir projenin TypeScript i nasil kullandigi — dilin tip guvencesini benimseyip benimsemedigi veya bosluklarla dolu, gecici bir alt kumeyle yetinip yetinmedigi — genellikle kod tabaninin zamanla nasil yaslandigini belirler.

Bu yazi, en cok fark yaratan kalip ve uygulamalari kapsamaktadir. 2026 yilina geldigimizde, bu tekniklerin bir cogu eski TypeScript versiyonlarinda zaten yerlesik hale gelmis olacak. Burada amac, yalnizca dilin su an neler yapabilecegini degil, ekibinizin her gun kullandigi kodu daha ifade edici ve daha az hata egilimli hale getirmek icin bu araclari nasil uygulayacagini gostermektir.

Tagged union lar: Derleyicinin sizin icin calismasini saglamak

Tagged union (ayrimci birlik), TypeScript tip sistemindeki en guclu desenlerden biridir. Her uyenin ortak bir literal tip alana (etiket) sahip oldugu bir birlik turudur. TypeScript, bu etiketi daraltma (narrowing) icin kullanabilir. Etikete baktiginiz anda, derleyici o daldaki verinin tam sekli hakkinda her seyi bilir.

type Result<T, E> =
  | { success: true; data: T }
  | { success: false; error: E };

function handleResult(result: Result<User, ApiError>) {
  if (result.success) {
    // TypeScript knows: result.data is User
    console.log(result.data.name);
  } else {
    // TypeScript knows: result.error is ApiError
    console.error(result.error.message);
  }
}

Bu desenin guzelligi, catch blogundaki hatalar veya null donusler gibi klasik tuzaklari ortadan kaldirmasidir. Bir Result tipi, gerekli oldugunda hatayi islemeniz icin sizi zorlar — derleme zamaninda. Bu yaklasim, her zaman butunluk icinde islenebildigi icin istisnalara tercih edilir ve bu da ozellikle birden cok hata turune sahip karma Fonksiyonlarda degerlidir.

Branded tipler: Ilkel takintiyi onlemek

TypeScript yapisal olarak tiplenmistir. Iki tip ayni sekle sahipse, birbirinin yerine kullanilabilir. Bu cogu zaman kullanislidir, ancak ayni ilkel tipe (string, number) sahip ancak farkli anlamlara sahip degerleri birbirinden ayirt etmeye calistiginizda soruna yol acabilir.

type UserId = string & { readonly __brand: "UserId" };
type PostId = string & { readonly __brand: "PostId" };

function getUser(id: UserId): User { /* ... */ }
function getPost(id: PostId): Post { /* ... */ }

const uid = "abc123" as UserId;
const pid = "xyz789" as PostId;

getUser(pid); // Error: Type 'PostId' is not assignable to type 'UserId'
getPost(uid); // Error: Type 'UserId' is not assignable to type 'PostId'

Branded tip olusturmak icin, kurgusal bir __brand ozelligine sahip bir kesisim turu kullanirsiniz. Bu ozellik calisma zamaninda mevcut degildir; TypeScript in onu benzersiz olarak gormesi icin bir derleme zamani yapisidir. Kullanici girdisinin dogrulandigi, UUID lerin belirli bir formata uydugu veya ayni ilkel tipin kod tabani boyunca birden cok anlama sahip oldugu sinirlarda as TypeScript donusumu yaparsiniz.

Branded tipler, ozellikle buyuk kod tabanlarinda ve API sinirlarinda degerlidir. Bir UserId ve bir SessionId nin her ikisi de string oldugunda, hata turunu ters sirayla kullanmak cok kolaydir. Derleme zamaninda calisan bir branded tip, hatalarin calisma zamaninda ortaya cikmasini onler.

Assertion fonksiyonlari: Altyapiyi basit tutmak

Assertion fonksiyonlari, TypeScript 3.7 de tanitilmistir ve dar bir kullanima sahip gibi gorunseler de, do rulama mantigini tip guvenliginden odun vermeden basitlestirmenin en pratik yollarindan biridir. Bir assertion fonksiyonu, cagri basarili olursa belirli bir daraltmanin gecerli oldugunu derleyiciye soyler.

function assertIsDefined<T>(value: T | undefined | null): asserts value is T {
  if (value === undefined || value === null) {
    throw new Error("Value is undefined or null");
  }
}

function processConfig(config: Config | undefined) {
  assertIsDefined(config);
  // TypeScript knows: config is Config
  console.log(config.timeout);
}

Daraltma fonksiyonlarindan farkli olarak, assertion fonksiyonlari bir boolean dondurmek yerine bir istisna firlatir. Bu, bir hata firlatilincaya kadar bir degerin gecerli oldugunu bilmenin mantikli oldugu akis kontrolu icin idealdir Dunyaya acilan sinir (API istegi, veri tabani sorgusu, kullanici girdisi) bir degerin beklendigi gibi olup olmadigini onceden kontrol edemediginiz tek yerdir.

Assertion fonksiyonlari, sinirlari dogrulamak icin kullanildiginda en gucludur. Giris dogrulamasi icin kullandiginiz bir Zod semasi turunu cikarabilir ve assertion fonksiyonu veriyi onayladiktan sonra da cikarilan turun kullanilmasini saglayabilirsiniz.

Haritalanmis tipler: Tur transformasyonlari

Haritalanmis tipler (mapped types), mevcut bir tipi almaniza ve her bir ozelligi donusturerek yeni bir tip olusturmaniza olanak tanir. TypeScript in Partial, Required ve Readonly gibi bircok yardimci tipi, haritalanmis tipler kullanilarak olusturulmustur. Ancak haritalanmis tiplerin gercek gucu, kendi donusum mantiginizi olusturdugunuzda ortaya cikar.

type ApiResponse<T> = {
  [K in keyof T]: {
    value: T[K];
    error?: string;
    timestamp: number;
  };
};

type User = {
  name: string;
  email: string;
  age: number;
};

// {
//   name: { value: string; error?: string; timestamp: number };
//   email: { value: string; error?: string; timestamp: number };
//   age: { value: number; error?: string; timestamp: number };
// }
type UserApiResponse = ApiResponse<User>;

Bu desen, API katmani, form durumu veya her bir alanin baslangic degeri, dogrulama durumu ve meta veriye ihtiyac duydugu herhangi bir senaryo icin kullanisli bir yapidir.

Haritalanmis tipler, kosullu tiplerle birlestirildiginde daha da guclu hale gelir. Kosullu tipler (T extends U ? X : Y), turlere mantik eklemenize olanak tanir ve bu sayede donusumlerinizi alanin kendisine gore uyarlayabilirsiniz.

type FormState<T> = {
  [K in keyof T]: T[K] extends string
    ? { value: T[K]; error?: string }
    : T[K] extends number
      ? { value: T[K]; min?: number; max?: number }
      : { value: T[K] };
};

Bu tur sayesinde string alanlari otomatik olarak bir hata alani alirken, sayisal alanlar min ve max kisitlamalari alir. Butun bunlar derleme zamani guvenligi ile saglanir.

En iyi uygulamalar: Ekibinizin uzerinde anlasmasi gerekenler

Tip teknikleri yalnizca baslangictir. Bunlarin degerli olmasi icin ekip duzeyinde bir sekilde kabul gormesi gerekir. Bir kisi branded tipler kullanirken, onu gormeyen baska biri ayni degerler uzerinde asiri genis bir string tipiyle calisiyorsa, tip sistemi uyumunu kaybeder. Iste deneyimli TypeScript ekiplerinin cesitli projelerde fikir birligine vardigi birkac ilke.

  • Acik tip sablonlarindan kacinin. Bilinmeyen bir API donus tipi icin any cogu zaman gereklidir, ancak uygulama mantiginizda herhangi bir tipte bosluk birakmamaya ozen gostermelisiniz.
  • Yardimci tipleri uygulamaniza ozgu olmayan bir yerde tutun. Bu sekilde ekipteki herkes ayni yapi taslarini kullanir.
  • Tasarladiginiz gercek bir neden yoksa ihrac edilmis tipler icin indeks erisimli tipler (T[K]) kullanin. Bunlar basit gorunur ancak okunmasi ve hata ayiklanmasi zor olabilir.
  • Sadece gerekli oldugunda generic tip kullanin. Generic tipler kodu yeniden kullanilabilir hale getirir ancak okunabilirligi de azaltir. Bazen iki ayri ozel tip bir generic tipten daha iyidir.
  • Ihrac edilen fonksiyonlar icin parametrelerin tipini ve donus degerinin tipini (mumkunse) acikca belirtin. Donus tipi cikarimi pratiktir ancak imza seviyesinde tip guvenligini saglar.

TypeScript, kontrollu bir sekilde kullanildiginda en gucludur. Dilin sundugu tum ozellikleri kullanmak caziptir, ancak ciddi projelerde sadeligin istikrarli oldugu kanitlanmistir.