Utility types, TypeScript'e yerleşik olan ve bir tipi başka bir tipe dönüştüren generic tiplerdir. Her alanı isteğe bağlı ikinci bir User tipi yazmak yerine Partial<User> yazarsınız; üç alanı kopyalamak yerine Pick<User, "id" | "name">. Global oldukları için import gerekmez.
User değiştiğinde türetilen dört tip de onu takip eder. TypeScript'in standart kütüphanesi (lib.es5.d.ts) 22 utility type bildirir. Aşağıdaki bölümler hepsini, üzerinde çalıştıkları tip türüne göre gruplanmış olarak ve varsa ayrıntılı sayfanın bağlantısıyla listeler.
Nesne Tipleri: Partial, Required, Readonly, Pick, Omit, Record
| Utility type | Ne yapar | Örnek |
|---|---|---|
Partial<T> | her özelliği isteğe bağlı yapar | güncelleme verisi için Partial<User> |
Required<T> | her özelliği zorunlu yapar (? işaretini kaldırır) | varsayılanlar uygulandıktan sonra Required<Config> |
Readonly<T> | her özelliği readonly yapar | Readonly<State> |
Pick<T, K> | yalnızca K anahtarlarını tutar | Pick<User, "id" | "name"> |
Omit<T, K> | K anahtarlarını çıkarır | Omit<User, "password"> |
Record<K, V> | anahtarları K, değerleri V olan bir nesne tipi | Record<"en" | "de", string> |
Required<T>, Partial<T> tipinin tersidir; Partial sayfası ikisini de, bunun gibi bir spread'in içeri aldığı açık undefined dahil, ele alır.
Union Tipleri: Exclude, Extract, NonNullable
| Utility type | Ne yapar | Örnek |
|---|---|---|
Exclude<U, M> | M tipine atanabilen union üyelerini çıkarır | Exclude<"a" | "b" | "c", "a"> sonucu "b" | "c" |
Extract<U, M> | M tipine atanabilen union üyelerini tutar | Extract<string | number, number> sonucu number |
NonNullable<T> | null ve undefined değerlerini çıkarır | NonNullable<string | null> sonucu string |
Bu üçü nesneler üzerinde değil union'lar üzerinde çalışır. Bir nesne tipi ve onun anahtarlarından bir liste alan Pick ve Omit ile temel fark budur.
Fonksiyon ve Class Tipleri: Parameters, ReturnType ve Dahası
| Utility type | Ne yapar | Örnek |
|---|---|---|
ReturnType<F> | bir fonksiyon tipinin dönüş tipi | ReturnType<typeof createStore> |
Parameters<F> | parametre tipleri, bir tuple olarak | Parameters<typeof fetchPage>[0] |
ConstructorParameters<C> | bir class constructor'ının parametreleri, bir tuple olarak | ConstructorParameters<typeof Point> |
InstanceType<C> | bir constructor'ın oluşturduğu instance tipi | InstanceType<typeof Point> |
ThisParameterType<F> | bir fonksiyonun this parametresinin tipi | ThisParameterType<typeof greet> |
OmitThisParameter<F> | this parametresi olmadan fonksiyon tipi | greet.bind(obj) ifadesinin tipi |
ThisType<T> | bir nesne literal'inin metotları içinde this tipini belirler | builder API'lerinde noImplicitThis ile kullanılır |
NoInfer<T> | bir tip parametresinin bu konumdan çıkarılmasını engeller | fallback: NoInfer<C> |
typeof createOrder gereklidir, çünkü bu utility'ler bir tip alır ve createOrder bir değerdir. Class'lar için de aynısı geçerlidir: typeof Point constructor tipidir, tip olarak yazılan düz Point ise zaten instance tipi anlamına gelir.
NoInfer, bir generic'in tipini nereden alacağını kontrol eder:
NoInfer olmasaydı TypeScript C tipini iki argümandan da çıkarır ve "red" | "green" | "blue" olarak genişletirdi; böylece fallback'teki yazım hatası kabul edilirdi.
String Tipleri: Uppercase, Lowercase, Capitalize, Uncapitalize
| Utility type | Ne yapar | Örnek |
|---|---|---|
Uppercase<S> | bir string literal tipini büyük harfe çevirir | Uppercase<"get"> sonucu "GET" |
Lowercase<S> | küçük harfe çevirir | Lowercase<"GET"> sonucu "get" |
Capitalize<S> | ilk karakteri büyük harf yapar | Capitalize<"name"> sonucu "Name" |
Uncapitalize<S> | ilk karakteri küçük harf yapar | Uncapitalize<"Name"> sonucu "name" |
Bu dördü TypeScript ile yazılmamıştır, derleyicinin içine yerleşiktir ve en çok template literal types içinde işe yarar; örneğin olay işleyici adları için `on${Capitalize<E>}`.
Promise'ler: Awaited
| Utility type | Ne yapar | Örnek |
|---|---|---|
Awaited<T> | await ile elde ettiğiniz tip, iç içe promise'leri açar | Awaited<Promise<Promise<number>>> sonucu number |
Awaited<ReturnType<typeof fn>>, bir async fonksiyonun sonuç tipini ayrıca bildirmeden adlandırmanın standart yoludur.
Utility Type'ları Birleştirmek
Utility type'lar iç içe kullanılabilir. Bazı birleşimler ezbere bilinmeye değecek kadar sık karşınıza çıkar:
İç içe bir utility type'ı içten dışa doğru okuyun: Readonly<Pick<Post, "id" | "title">> önce iki özelliği tutar, sonra onları salt okunur yapar. Aynı parçalar yalnızca bazı anahtarları isteğe bağlı yapan bir PartialBy yardımcısı kurar; Partial sayfası onu açıkça yazar.
Utility Type'lar Çalışma Zamanında Hiçbir Şey Yapmaz
Kod derlendiğinde her utility type silinir. Omit<User, "password"> tipindeki bir değer, geldiği nesnede bir password varsa çalışma zamanında onu hâlâ taşıyabilir:
Tip yalnızca kodunuzun neyi okuyabileceğini sınırlar. Bir alanı veriden çıkarmak için son satırlardaki gibi destructuring ile ayırın; çalışma zamanında değişikliği durdurmak için Readonly değil Object.freeze kullanın. Yerleşik tipler tek satırlık mapped type ve conditional type'lardır, dolayısıyla aynı araçlarla kendi tiplerinizi de yazabilirsiniz.
Sıkça Sorulan Sorular
TypeScript'te utility types nedir?
TypeScript ile birlikte gelen ve başka tipleri dönüştüren generic tiplerdir: Partial<T> her özelliği isteğe bağlı yapar, Pick<T, K> bazı özellikleri tutar, ReturnType<F> bir fonksiyonun dönüş tipini verir ve bunun gibi. Standart kütüphanede bildirildikleri için hiçbir şey import etmeden kullanırsınız.
Utility type'ları import etmem gerekir mi?
Hayır. Partial, Omit, Record, ReturnType ve diğerleri TypeScript'in yerleşik kütüphane dosyalarındaki global tiplerdir. Partial<User> ifadesini her yerde yazabilirsiniz; import ya da npm paketi gerekmez.
TypeScript'te hangi utility type'lar yerleşiktir?
Hepsi lib.es5.d.ts içinde bildirilen 22 tane: Partial, Required, Readonly, Pick, Omit, Record, Exclude, Extract, NonNullable, Parameters, ConstructorParameters, ReturnType, InstanceType, ThisParameterType, OmitThisParameter, ThisType, NoInfer, Awaited, Uppercase, Lowercase, Capitalize ve Uncapitalize.
Utility type'lar nesneleri çalışma zamanında değiştirir mi?
Hayır. Yalnızca tipleri tanımlarlar ve JavaScript çıktısından silinirler. Omit<User, "password"> bir password özelliğini silmez, Readonly<T> da hiçbir şeyi dondurmaz. Gerçek nesneyi değiştirmek için kodu yazın: bir destructuring rest deseni, Object.freeze ve benzeri.
Kendi utility type'larımı yazabilir miyim?
Evet. Yerleşik olanlar sıradan TypeScript'tir: çoğu lib.es5.d.ts içinde tek satırlık mapped type ya da conditional type'dır. type Nullable<T> = { [K in keyof T]: T[K] | null } aynı şekilde yazılmış özel bir utility type'tır.