Exclude<T, U> bir union tipinden üye çıkarır, Extract<T, U> yalnızca eşleşen üyeleri tutar, NonNullable<T> ise null ve undefined değerlerini çıkarır. Üçü de union'ları filtreler; nesne özelliklerine dokunmazlar.
Her utility type gibi bunlar da yalnızca derleme zamanında vardır. Son satırı derleyici reddeder; çalışan JavaScript'in Visible tipinin ne olduğundan haberi yoktur.
Bir Bakışta Exclude, Extract ve NonNullable
| Tip | Tuttuğu | Örnek | Sonuç |
|---|---|---|---|
Exclude<T, U> | T üyelerinden U tipine atanamayanlar | Exclude<"a" | "b" | "c", "a"> | "b" | "c" |
Extract<T, U> | T üyelerinden U tipine atanabilenler | Extract<"a" | "b" | "c", "a" | "z"> | "a" |
NonNullable<T> | null ve undefined dışındaki her şey | NonNullable<string | null | undefined> | string |
Anahtar ifade "U tipine atanabilir" ifadesidir. U tam üyelerden oluşan bir liste olmak zorunda değildir; birkaç üyenin uyduğu daha geniş bir tip olabilir:
Union Üyelerini Şekle Göre Seçmek
Bir discriminated union üzerinde, kısmi bir şekille kullanılan Extract o şekle sahip varyantları çeker. Kendiniz yazmadığınız bir union'ın bir varyantını adlandırmanın olağan yolu budur:
{ type: "click" } şekli yalnızca click varyantının bir üst tipidir, bu yüzden Extract onu tutar. Birkaç varyantla eşleşen bir şekil (örneğin ikisinde de varsa { x: number }) hepsini tutar.
NonNullable
NonNullable<T>, bir !== null && !== undefined kontrolünün tip sürümüdür. İsteğe bağlı bir şeyden tip türettiğinizde karşınıza çıkar:
User["manager"] tipi { name: string } | null | undefined olur (? işareti undefined ekler) ve NonNullable ikisini de çıkarır. TypeScript 5.5'ten beri derleyici bu predicate'i kendi başına da çıkarır, yani raw.filter((s) => s != null) zaten string[] olarak tiplenir; açık s is NonNullable<typeof s> niyeti görünür tutar ve eski sürümlerde de çalışır. Tanımı type NonNullable<T> = T & {} şeklindedir: boş nesne tipi {}, null ve undefined dışındaki her değeri kabul eder, bu yüzden onunla kesiştirmek tam olarak bu ikisini çıkarır.
Nasıl Kurulurlar
Exclude ve Extract, standart kütüphanede tek satırlık conditional type'lardır:
type Exclude<T, U> = T extends U ? never : T;
type Extract<T, U> = T extends U ? T : never;
T bir union olduğunda conditional type her üyeye ayrı ayrı uygulanır (dağılır) ve never üyeler sonuçtan kaybolur. Böylece Exclude<"a" | "b", "a"> önce ("a" extends "a" ? never : "a") | ("b" extends "a" ? never : "b") olur, bu da never | "b", yani "b" demektir. Dağılmayı conditional types sayfası ayrıntılı ele alır.
Exclude ile Omit, Extract ile Pick
Adlar kolayca karışır, çünkü iki çift de bir şeyi "çıkarır" ya da "tutar". Fark, üzerinde çalıştıkları şeydedir:
| Üzerinde çalıştığı | Çıkardığı ya da tuttuğu | Örnek | |
|---|---|---|---|
Exclude<T, U> | bir union | union üyeleri | Exclude<"a" | "b", "a"> → "b" |
Extract<T, U> | bir union | union üyeleri | Extract<"a" | "b", "a"> → "a" |
Omit<T, K> | bir nesne tipi | özellikler | Omit<User, "password"> |
Pick<T, K> | bir nesne tipi | özellikler | Pick<User, "name"> |
Exclude tipini bir nesne tipi üzerinde kullanmak yaygın bir hatadır ve sessizce başarısız olur:
Account, "password" tipine atanamaz, bu yüzden Exclude onu olduğu gibi tutar. Omit'in kendisi anahtarlara uygulanan Exclude ile kurulmuştur: Omit<T, K>, Pick<T, Exclude<keyof T, K>> tipidir. Daha fazlası için Omit sayfasına bakın.
Daha Katı Bir Exclude
Exclude tipinin ikinci parametresi her tipi kabul eder, bu yüzden bir yazım hatası hiçbir şey çıkarmaz ve hata da vermez. Bir kısıtlama eklemek, derleyicinin exclude ettiğiniz şeyin gerçekten union'da olduğunu kontrol etmesini sağlar:
index.ts(7,37): error TS2344: Type '"drafft"' does not satisfy the constraint 'Status'.
Yazımı düzeltin, derlenir ve Strict tipi "published" | "archived" olur. Aynı yöntem Extract için ve katı bir Omit (K extends keyof T) için de çalışır.
Sıkça Sorulan Sorular
TypeScript'te Exclude ne işe yarar?
Exclude<T, U>, T union'ından U tipine atanabilen her üyeyi çıkarır. Exclude<"a" | "b" | "c", "a"> sonucu "b" | "c" olur. Birden fazla üye çıkarmak için U olarak bir union geçirin: Exclude<T, "a" | "b">.
Exclude ile Extract arasındaki fark nedir?
Birbirlerinin tersidirler. Exclude<T, U>, T üyelerinden U tipine atanamayanları tutar; Extract<T, U> ise yalnızca atanabilenleri tutar. Aynı T ve U için iki sonuç birlikte T tipini oluşturur.
Exclude ile Omit arasındaki fark nedir?
Exclude bir union tipi üzerinde çalışır ve union üyelerini çıkarır. Omit bir nesne tipi üzerinde çalışır ve özellikleri çıkarır. Exclude<User, "password"> işe yarar bir şey yapmaz (User döndürür), Omit<User, "password"> ise o özellik olmadan nesne tipini verir. Omit, Exclude üzerine kuruludur: anahtarı keyof T içinden exclude eder.
TypeScript'te NonNullable ne işe yarar?
NonNullable<T> bir tipten null ve undefined değerlerini çıkarır: NonNullable<string | null | undefined> sonucu string olur. T & {} olarak tanımlanmıştır, çünkü {} tipi null ve undefined dışındaki her değeri kabul eder.
Exclude var olmayan bir üye için neden hata vermiyor?
İkinci parametresi kısıtlanmamıştır; bu yüzden her tip kabul edilir ve Exclude<Status, "drafft"> gibi bir yazım hatası sessizce hiçbir şey çıkarmaz. Derleyicinin U tipinin T tipinin parçası olduğunu kontrol etmesi için daha katı bir sürüm tanımlayın: type StrictExclude<T, U extends T> = Exclude<T, U>.