Cansu Arı Logo
Blog
Nasıl Yapılır?

TypeScript Utility Types ile Kod Tekrarını Yok Etmek

TypeScript’in gizli kahramanları: Partial, Pick, Omit. Daha az kod, daha fazla güvenlik!

  • #TypeScript
  • #Performans

Skip to content

Daha Az Kod, Daha Çok Tip: Utility Types Rehberi

Kod tekrarı (yani DRY kuralını ihlal etmek), her geliştiricinin kâbusudur. Kopyala-yapıştır cenneti gibi görünür ama zamanla refactor cehennemine dönüşür. 😊 Neyse ki TypeScript bu konuda yalnız değilsin diyor ve elimize bir avuç sihirli araç veriyor: Utility Types!

Bu küçük ama etkili tip yardımcıları, tipleri yeniden tanımlamak yerine onları dönüştürmene, sadeleştirmene ve yeniden kullanmana olanak tanır. Hem kodu temizler, hem de tip güvenliğini artırır. Kısacası: daha az kod, daha fazla akıl sağlığı.

Partial

Bir tipin tüm alanlarını opsiyonel hale getirir. Özellikle update, patch veya form işleme fonksiyonlarında harika işler çıkarır.
type User = { id: number; name: string; age: number };
const updateUser = (user: Partial<User>) => {
// sadece değişen alanlar gönderilebilir
};

Artık updateUser({ name: 'Cansu' }) gayet geçerli. Çünkü Partial sayesinde User tipinin tüm alanları artık isteğe bağlı.

Bonus: Partial’ı derin yapılarda kullanmak istersen, DeepPartial adında custom versiyonlar da yaratabilirsin.

Pick

Bir tipten sadece belirli alanları seçmek istediğinde Pick imdadına yetişir.
type User = { id: number; name: string; age: number; email: string };
type UserPreview = Pick<User, 'id' | 'name'>;

Artık UserPreview sadece id ve name alanlarını içerir. Listeleme sayfalarında ya da basit kart bileşenlerinde tam da ihtiyacın olan şeydir.

Omit

Pick’in kardeşi ama biraz huysuz olanı. ☺️ Belirli alanları hariç tutar.
type UserWithoutAge = Omit<User, 'age'>;

Yani UserWithoutAge, User tipinden age alanını çıkarır. Özellikle hassas veya gereksiz alanları arayüzden soyutlamak için kullanılır.

Record

Bir anahtar-değer eşleşmesi oluşturmak istediğinde Record mükemmel bir çözümdür. Sözlük gibi çalışır.
type Roles = 'admin' | 'user';
const permissions: Record<Roles, boolean> = {
admin: true,
user: false,
};

Artık permissions.admin ya da permissions.user dediğinde otomatik olarak tip kontrolü alırsın. Yanlış role yazarsan TypeScript anında kızar (ama sevgiyle 💙).

Readonly ve Required

Readonly<T> → Objeleri değiştirilemez hale getirir. Required<T> → Opsiyonel alanları zorunlu hale getirir.

Bu ikili, özellikle API response’larını ya da config objelerini koruma altına almak için birebirdir.

type Config = { apiKey?: string; version?: number };
type StrictConfig = Required<Readonly<Config>>;

Artık bu yapıdaki alanları ne eksik gönderebilir ne de değiştirebilirsin. Güvenli, sert, tam bir TypeScript bodyguard’ı.

ReturnType ve Parameters

Bir fonksiyonun dönüş veya parametre tipini tekrar yazmak yerine otomatik çıkarabiliriz.
function createUser(name: string, age: number) {
return { name, age, active: true };
}

type UserReturn = ReturnType<typeof createUser>; // { name: string; age: number; active: boolean }

Aynı şekilde Parameters<typeof createUser> sana [string, number] şeklinde bir tuple döner. Böylece fonksiyon imzalarıyla oynarken tip uyumsuzlukları tarihe karışır.

Exclude ve Extract

Bu iki kardeş tam bir zıt kutup ikilisi:
  • Exclude<T, U> → T tipinden U’yu hariç tutar.
  • Extract<T, U> → Sadece U’ya uyan kısımları seçer.
type Status = 'pending' | 'success' | 'error';
type NonError = Exclude<Status, 'error'>; // 'pending' | 'success'

Böylece union tipleri üzerinde ince ayar yapabilirsin.

Neden Kullanılır?

  • Kod tekrarını ciddi şekilde azaltır.
  • Tip güvenliğini artırır.
  • Refactor sırasında hata riskini düşürür.
  • Karmaşık tipleri sadeleştirir.
  • Büyük ekiplerde ortak tiplerin sürdürülebilirliğini sağlar.
  • Ve en önemlisi: “Bu tip zaten vardı, neden bir daha yazdık?” krizlerini önler. 🙃

Gerçek Hayat Örneği

Bir API response tipini düşünelim:
type ApiResponse<T> = {
data: T;
status: number;
error?: string;
};

Bunu kullanarak yüzlerce endpoint’i tek bir yapı üzerinden tipleyebilirsin. ApiResponse<User> ya da ApiResponse<Product> gibi türevler sayesinde backend ve frontend arasında tam bir tip senkronu sağlanır. Utility Types bu tür esnek, modüler sistemler için altın değerindedir.

Sonuç

Utility Types, TypeScript’in gizli kahramanlarıdır. Daha az kod, daha fazla düzen, daha az hata, daha fazla huzur. Kodun okunabilirliği artar, refactor korkusu azalır ve proje ölçeklense bile tip sistemi seninle birlikte büyür.

Utility Types kullanmak sadece akıllıca değil, aynı zamanda tembeller için zekice bir harekettir. 😊

All tags
  • TypeScript
  • Performans