Bir union tip alternatifleri | ile listeler: string | number tipindeki bir değer ya bir string ya da bir sayıdır. Union'lar, TypeScript'in meşru olarak birden fazla biçim alabilen değerleri tanımlama yoludur ve derleyici, o biçime özgü bir şeyi kullanmadan önce hangi biçime sahip olduğunuzu kontrol etmenizi ister.
typeof kontrolünün her dalında id tek bir tipe sahiptir. Bu adıma daraltma (narrowing) denir ve union'ları pratik kılan da budur.
Yalnızca Ortak Üyelere İzin Verilir
Daraltmadan önce yalnızca union'ın her üyesinin desteklediği şeyleri kullanabilirsiniz. toString() hem string'lerde hem sayılarda vardır, bu yüzden sorun yoktur; toUpperCase() ise yalnızca string'lerde vardır:
index.ts(3,16): error TS2339: Property 'toUpperCase' does not exist on type 'string | number'.
Property 'toUpperCase' does not exist on type 'number'.
İkinci satır, özelliği eksik olan üyeyi adıyla söyler. Aynı kural diğer yönde de geçerlidir: bir string | number değeri string olarak tiplenmiş bir parametreye verilemez (TS2345), çünkü bir sayı olabilir. Bir union daha fazla değer kabul eder ve karşılığında siz kontrol edene kadar onlarla daha az şey yapmanıza izin verir.
Bir Union'ı Daraltmak
Daraltma sıradan JavaScript kontrollerini kullanır. TypeScript kontrol akışını izler ve elendikçe üyeleri çıkarır, böylece son kontrolden sonra yalnızca bir üye kalır:
| Kontrol | Daralttığı | Uygun olduğu |
|---|---|---|
typeof x === "string" | primitive'e | string, number, boolean, bigint, symbol, undefined, function |
x === null, x === "a" | karşılaştırılan değere | null, undefined, literal üyeler |
Array.isArray(x) | dizi üyesine | diziler |
x instanceof Date | sınıfa | sınıf örnekleri |
"meow" in x | o özelliğe sahip üyelere | nesne tipleri |
x.kind === "circle" | o etiketi taşıyan üyeye | discriminated union'lar |
isCat(x) (x is Cat döndürür) | fonksiyonun söylediğine | her şey, özel mantık |
Daraltma biçimlerinin tam listesi tip daraltma sayfasında.
Literal Tiplerin Union'ları
Literal değerlerin bir union'ı, izin verilen değerlerin kapalı bir kümesidir. Gerçek kodda en yaygın union budur:
type Status = "idle" | "loading" | "success" | "error";
type Dice = 1 | 2 | 3 | 4 | 5 | 6;
type Toggle = "on" | "off" | boolean; // boolean is itself true | false
let current: Status = "idle";
current = "loading"; // fine
current = "finished"; // error TS2322: Type '"finished"' is not assignable to type 'Status'.
Bir literal ile karşılaştırmak daraltır: if (current === "error") sonrasında else dalı current değerinin diğer üç değerden biri olduğunu bilir. Literal union'lar pek çok kod tabanında enum'ların yerini alır; as const ve böyle bir union'ı bir diziden türetmek için literal tipler sayfasına bakın.
Nesne Tiplerinin Union'ları
Üyeler nesne tipleri olduğunda, hepsinin paylaştığı özellikler doğrudan kullanılabilir. Geri kalanlar için özelliğin var olduğunu in ile kontrol edin:
Birkaç nesne biçiminden oluşan union'lar için daha temiz kalıp, kind: "cat" / kind: "fish" gibi ortak bir literal özelliktir. O tek özelliği kontrol etmek nesnenin tamamını daraltır ve onun üzerindeki bir switch kapsamlılık açısından kontrol edilebilir. Bu kalıp bir discriminated union'dır.
Diziler ve Union'lar
Parantezlerin nereye konduğu anlamı tamamen değiştirir:
| Tip | Anlamı | Örnek değer |
|---|---|---|
(string | number)[] | her elemanı bir string ya da bir sayı olan bir dizi | [1, "two", 3] |
string[] | number[] | yalnızca string'lerden ya da yalnızca sayılardan oluşan bir dizi | ["a", "b"] |
string | number[] | bir string ya da bir sayı dizisi (|, [] işaretinden daha gevşek bağlanır) | "text" |
Bir (string | number)[] üzerinde dolaşırken her eleman union'dır ve yukarıdaki reduce callback'inde olduğu gibi daraltma gerektirir. map ve filter gibi metotlar bir string[] | number[] üzerinde de çalışır; callback string | number alır.
null ve undefined ile Union'lar
En yaygın union "bir değer ya da hiçbir şey"dir: string | null, User | undefined. Array.prototype.find ve Map.prototype.get bunu döndürür ve opsiyonel bir name?: string özelliği string | undefined olarak okunur. Bunları ?., ?? ve null kontrolleriyle ele almanın kendi sayfası var: null ve undefined.
Mevcut bir union'dan tip düzeyinde üye çıkarmak için yerleşik yardımcıları kullanın: Exclude<"a" | "b" | "c", "a"> sonucu "b" | "c", NonNullable<string | null> sonucu da string olur.
Sıkça Sorulan Sorular
TypeScript'te union tip nedir?
| ile birleştirilmiş birkaç alternatiften oluşan bir tiptir. string | number tipindeki bir değer bir string ya da bir sayı olabilir. Derleyici, değeri typeof value === "string" gibi bir kontrolle tek bir üyeye daraltana kadar yalnızca tüm üyelerin ortak olarak sahip olduklarını kullanmanıza izin verir.
TypeScript neden bir özelliğin union tipte var olmadığını söylüyor?
Çünkü union'ın en az bir üyesinde o özellik yoktur. Örneğin Property 'toUpperCase' does not exist on type 'string | number' şeklindeki TS2339 hatası, değerin toUpperCase metodu olmayan bir sayı olabileceği anlamına gelir. Önce daraltın (typeof, in, Array.isArray, instanceof ya da bir ayırıcı kontrolü), sonra üyeye özgü özelliği kullanın.
Birden fazla tip tutan bir dizi nasıl tanımlanır?
Union'ı parantez içine alın: (string | number)[] veya Array<string | number>; burada her eleman iki tipten biri olabilir. string[] | number[] farklıdır: dizinin tamamı ya hep string ya da hep sayıdır. Parantez olmadan string | number[], bir string ya da bir sayı dizisi anlamına gelir.
Union ile intersection tip arasındaki fark nedir?
Bir union A | B, tiplerden biri olan bir değerdir, bu yüzden yalnızca ortak olanları kullanabilirsiniz. Bir intersection A & B ise aynı anda ikisi birden olan bir değerdir, bu yüzden ikisinin de tüm üyelerine sahiptir. Nesne tipleri için A | B daha fazla değer kabul eder, A & B ise daha fazla özellik gerektirir.
Bir union değerinin hangi tipte olduğunu nasıl kontrol ederim?
TypeScript'in anladığı bir çalışma zamanı kontrolü kullanın: primitive'ler için typeof x === "string", diziler için Array.isArray(x), sınıflar için x instanceof Date, nesne biçimleri için "prop" in x ya da üyeler ortak bir literal etiket paylaşıyorsa x.kind === "circle". Özel mantık için x is T döndüren bir type guard fonksiyonu yazın.