Bir TypeScript tuple'ı, eleman sayısı sabit olan ve her konumun kendi tipine sahip olduğu bir dizidir. [string, number] tam olarak iki eleman demektir: önce bir string, sonra bir sayı. Tipleri, değerlerin göründüğü sırayla köşeli parantez içinde yazarsınız.
Çalışma zamanında bir tuple düz bir JavaScript dizisidir. Bir tuple'ın eklediği her şey (sabit uzunluk ve her konumdaki tip) derleyici tarafından kontrol edilir ve silinir.
Tuple Sözdizimi
| Tuple tipi | Kabul ettiği | length tipi |
|---|---|---|
[string, number] | tam olarak bir string, sonra bir sayı | 2 |
[x: number, y: number] | aynısı, okunabilirlik için etiketlerle | 2 |
[number, number, number?] | 2 veya 3 sayı | 2 | 3 |
[string, ...number[]] | bir string, sonra istenen sayıda sayı | number |
[...string[], number] | istenen sayıda string, sonra bir sayı | number |
readonly [number, number] | değiştirilemeyen bir çift | 2 |
[] | yalnızca boş bir dizi | 0 |
Her biçim aşağıda açıklanıyor. length tipine dikkat etmeye değer: sabit bir tuple için bir literal tiptir, yani derleyici pair.length değerinin tam olarak 2 olduğunu bilir.
Derleyicinin Kontrol Ettikleri
Bir tuple tipi eleman sayısını, sıralarını ve her konumdaki tipi sabitler. Herhangi birini yanlış yapmak derleme hatasıdır:
index.ts(2,7): error TS2322: Type '[string]' is not assignable to type '[string, number]'.
Source has 1 element(s) but target requires 2.
index.ts(3,36): error TS2322: Type 'number' is not assignable to type 'string'.
index.ts(3,40): error TS2322: Type 'string' is not assignable to type 'number'.
index.ts(5,16): error TS2493: Tuple type '[string, number]' of length '2' has no element at index '2'.
Düz bir dizi sonuncuyu asla yakalayamazdı: string[] için arr[2] sadece çalışma zamanında undefined olan bir string değeridir.
İsimli Tuple Elemanları
Etiketler her konumun ne anlama geldiğini belgeler. Tip ya da indeksleme şekli hakkında hiçbir şeyi değiştirmezler, ama editörler onları üzerine gelince ve imza ipuçlarında gösterir; bu da [number, number] ifadesini çok daha az gizemli kılar.
TypeScript 5.2'den beri bazı konumları etiketleyip diğerlerini etiketsiz bırakabilirsiniz, örneğin [first: string, number]. Etiketler yalnızca okuyucular içindir: [x: number, y: number] ve [number, number] aynı tiptir ve birbirine atanabilir.
Opsiyonel Elemanlar
Bir eleman tipinden sonra gelen ? o konumu opsiyonel yapar. Opsiyonel elemanlar zorunlu olanlardan sonra gelmelidir ve her biri length tipini genişletir.
Opsiyonel bir elemanı okumak T | undefined verir; bu yüzden aritmetikten önce destructuring kalıbında bir varsayılan değer (a = 1) ya da bir kontrol gerekir.
Rest Elemanlar
Bir rest eleman, ...T[], istenen sayıda T tipinde elemanı temsil eder. Sonda, başta ya da ortada olabilir; tuple başına en fazla bir tane.
Rest eleman içeren bir tuple'ın length tipi number olur, çünkü boyut artık sabit değildir. Sabit kalan, tipli konumların nerede olduğudur.
Readonly Tuple'lar ve as const
readonly [T, U], push, pop, splice ve indekse atamayı kaldırır; sabit uzunluklu bir değer de böyle olmalıdır. Bir dizi literal'inden sonra as const yazmak, literal tiplerden oluşan readonly bir tuple çıkarır.
(typeof SIZES)[number] tuple'ı eleman tiplerinin bir union'ına dönüştürür; bu kalıp indexed access types sayfasında anlatılıyor. Readonly bir tuple, değiştirilebilir tuple olarak tiplenmiş bir parametreye verilemez; bu yüzden yalnızca okuyan fonksiyonlar readonly [number, number] kabul etmelidir.
readonly kontrolü yalnızca derleme zamanındadır. Çalışma zamanında dizi dondurulmaz (yukarıdaki atama gerçekten çalıştı, çıktı bunu gösteriyor); çalışma zamanı garantisi gerekiyorsa Object.freeze kullanın.
Bir Fonksiyondan Tuple Döndürmek
Birden fazla değeri bir tuple olarak döndürmek, React'in useState fonksiyonunun çalışma şeklidir (const [value, setValue] = useState(0)). Püf noktası: bir return içindeki dizi literal'i tuple olarak değil, dizi olarak çıkarılır.
index.ts(9,13): error TS2365: Operator '+' cannot be applied to types 'number | (() => number)' and 'number'.
index.ts(10,1): error TS2349: This expression is not callable.
Not all constituents of type 'number | (() => number)' are callable.
Type 'number' has no call signatures.
Fonksiyon (number | (() => number))[] döndürür, bu yüzden destructuring ile alınan iki ad da union tipini alır. İki çözüm vardır: dönüş tipine notasyon yazmak ya da as const eklemek.
Tuple dönüş değeri, çağıranların parçalara istedikleri adı vermesine izin verir. İki üçten fazla değer olduğunda ya da sıra açık olmadığında bunun yerine bir nesne döndürün: { count, increment } kendini belgeler.
Fonksiyon Parametresi Olarak Tuple'lar
Tuple olarak tiplenmiş bir rest parametre, opsiyonel argümanlar dahil tüm argüman listesini tanımlar. Yerleşik Parameters<T> utility tipi bir fonksiyonun parametrelerini bu şekilde temsil eder.
Bir tuple'ı bir çağrıya yaymak (spread), her argümanı konumuna göre tip kontrolünden geçirir; (string | number)[] tipinde bir yayma bunu yapamazdı.
Tuple ile Dizi
Dizi (string | number)[] | Tuple [string, number] | |
|---|---|---|
| Uzunluk | herhangi | sabit (veya opsiyonel ve rest elemanlarla sınırlı) |
x[0] tipi | string | number | string |
x[5] tipi | string | number | TS2493 derleme hatası |
length tipi | number | 2 |
| Tiplerin sırası | izlenmez | izlenir |
| Çalışma zamanı değeri | JavaScript dizisi | aynı JavaScript dizisi |
| Tipik kullanım | benzer öğelerin listeleri | küçük sabit gruplar: çiftler, koordinatlar, [key, value], birden fazla dönüş değeri |
Tuple'lar yerleşik tiplerde de karşınıza çıkar. Object.entries(obj), [string, T][] döndürür ve bir Map, [key, value] tuple'larından oluşturulur:
Bir tuzak: değiştirilebilir bir tuple hâlâ her dizi metoduna sahiptir, bu yüzden pair.push(3) bir [string, number] üzerinde derlenir ve tipi iki eleman diyen üç elemanlı bir diziyi sessizce oluşturur. Tuple'ları readonly olarak tanımlamak bu açığı kapatır. Ayrıca tipler silindiği için program dışından gelen veriler (JSON, bir API) çalışma zamanında bir tuple tipine göre kontrol edilmez: güvenmeden önce uzunluğunu ve eleman tiplerini doğrulayın.
Variadic Tuple Tipleri
Tuple tipleri başka tuple tiplerini yayabilir, [...T, ...U]. Generic'lerle birleştiğinde bu, her konumu koruyarak birleştiren veya başa ekleyen fonksiyonlara tip verir:
Kütüphane tipleri de tuple çıkarımına dayanır: Promise.all([fetchUser(), fetchPosts()]) her girdi promise'i için bir tip içeren bir tuple'a çözümlenir.
Sıkça Sorulan Sorular
TypeScript'te tuple nedir?
Tuple, uzunluğu sabit olan ve her konumun kendi tipine sahip olduğu bir dizi tipidir: [string, number] tam olarak iki elemandır, önce bir string, sonra bir sayı. Çalışma zamanında sıradan bir JavaScript dizisidir; uzunluk ve konum başına tipler yalnızca derleme zamanında kontrol edilir.
TypeScript'te tuple ile dizi arasındaki fark nedir?
(string | number)[] gibi bir dizi tipi herhangi bir uzunluktadır ve her elemanı aynı (union) tipe sahiptir, yani arr[0] tipi string | number olur. [string, number] gibi bir tuple'ın uzunluğu bilinir; t[0] tipi string, t[1] tipi number olur ve t[2] bir derleme hatasıdır.
TypeScript'te bir fonksiyondan nasıl tuple döndürülür?
Dönüş tipine notasyon yazın, function f(): [number, string], ya da dönüş ifadesini readonly bir tuple veren as const ile bitirin. İkisi de yoksa return [count, setCount], (number | (() => void))[] gibi bir union dizisi olarak çıkarılır ve destructuring union tipler verir.
İsimli tuple elemanları nedir?
Konumlara verilen etiketlerdir, [name: string, age: number]. Tipi ya da erişim şeklini değiştirmezler (hâlâ t[0]), ama editörler onları üzerine gelince açılan ipuçlarında ve parametreleri tuple olarak tiplenmiş fonksiyonların parametre ipuçlarında gösterir. Opsiyonel ve rest elemanlar etiketlerle çalışır: [x: number, y?: number], [head: string, ...rest: number[]].
TypeScript'te bir tuple'a push yapılabilir mi?
Değiştirilebilir bir tuple'da evet: tuple'lar dizi metotlarını miras aldığı için push derlenir, sabit uzunluğu bozsa bile. Tuple'ı readonly olarak tanımlayın (veya as const ile oluşturun), push, pop ve indekse atama derleme hatası olur.