Menu

Tuple di TypeScript: Sintaks, Elemen Bernama, Opsional, Rest

Tuple di TypeScript adalah array dengan jumlah elemen tetap yang tipenya diketahui berdasarkan posisi, seperti [string, number]. Pelajari sintaksnya, elemen bernama, opsional, dan rest, tuple readonly dan as const, mengembalikan tuple dari fungsi, dan perbedaan tuple dengan array.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

Tuple di TypeScript adalah array dengan jumlah elemen yang tetap, dan setiap posisinya punya tipe sendiri. [string, number] berarti tepat dua elemen: string lebih dulu, lalu number. Kamu menulis tipenya di dalam kurung siku sesuai urutan nilainya.

Saat runtime, tuple adalah array JavaScript biasa. Semua yang ditambahkan tuple (panjang yang tetap dan tipe di setiap posisi) dicek oleh compiler lalu dihapus.

Sintaks Tuple

Tipe tupleMenerimaTipe length
[string, number]tepat sebuah string, lalu sebuah number2
[x: number, y: number]sama, dengan label supaya mudah dibaca2
[number, number, number?]2 atau 3 number2 | 3
[string, ...number[]]sebuah string, lalu number sebanyak apa punnumber
[...string[], number]string sebanyak apa pun, lalu sebuah numbernumber
readonly [number, number]pasangan yang tidak bisa diubah2
[]hanya array kosong0

Setiap bentuk dijelaskan di bawah. Tipe length layak diperhatikan: untuk tuple yang tetap, tipenya adalah literal type, jadi compiler tahu pair.length tepat bernilai 2.

Apa yang Dicek Compiler

Tipe tuple menetapkan jumlah elemen, urutannya, dan tipe di setiap posisi. Salah di salah satunya adalah error kompilasi:

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'.

Array biasa tidak akan pernah bisa menangkap yang terakhir: untuk string[], arr[2] hanyalah sebuah string yang kebetulan bernilai undefined saat runtime.

Elemen Tuple Bernama

Label mendokumentasikan arti setiap posisi. Label tidak mengubah apa pun pada tipe atau cara mengaksesnya lewat index, tetapi editor menampilkannya saat hover dan di petunjuk signature, sehingga [number, number] jauh lebih mudah dipahami.

Sejak TypeScript 5.2, kamu bisa memberi label pada sebagian posisi dan membiarkan yang lain tanpa label, seperti [first: string, number]. Label hanya untuk pembaca: [x: number, y: number] dan [number, number] adalah tipe yang sama dan bisa saling di-assign.

Elemen Opsional

? setelah tipe elemen membuat posisi itu opsional. Elemen opsional harus berada setelah elemen wajib, dan masing-masing melebarkan tipe length.

Membaca elemen opsional menghasilkan T | undefined, jadi dibutuhkan nilai default di pola destructuring (a = 1) atau pengecekan sebelum melakukan aritmetika.

Elemen Rest

Elemen rest, ...T[], mewakili elemen bertipe T sebanyak apa pun. Elemen ini boleh berada di akhir, di awal, atau di tengah, paling banyak satu per tuple.

length dari tuple dengan elemen rest adalah number, karena ukurannya tidak lagi tetap. Yang tetap adalah letak posisi-posisi yang bertipe.

Tuple Readonly dan as const

readonly [T, U] menghapus push, pop, splice dan assignment lewat index, dan memang begitulah seharusnya nilai dengan panjang tetap. Menulis as const setelah array literal akan menyimpulkan tuple readonly berisi literal type.

(typeof SIZES)[number] mengubah tuple menjadi union dari tipe elemennya, pola yang dibahas di indexed access types. Tuple readonly tidak bisa dikirim ke parameter bertipe tuple yang mutable, jadi fungsi yang hanya membaca sebaiknya menerima readonly [number, number].

Pengecekan readonly hanya berlaku saat kompilasi. Saat runtime, array-nya tidak dibekukan (assignment di atas benar-benar dijalankan, seperti yang terlihat di output), jadi pakai Object.freeze kalau kamu butuh jaminan saat runtime.

Mengembalikan Tuple dari Fungsi

Mengembalikan beberapa nilai sebagai tuple adalah cara kerja useState di React (const [value, setValue] = useState(0)). Masalahnya: array literal di return disimpulkan sebagai array, bukan tuple.

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.

Fungsi itu mengembalikan (number | (() => number))[], jadi kedua nama hasil destructuring mendapat tipe union. Ada dua perbaikan: beri anotasi tipe kembalian, atau tambahkan as const.

Nilai kembalian berupa tuple membuat pemanggil bebas memberi nama bagian-bagiannya. Kalau nilainya lebih dari dua atau tiga, atau urutannya tidak jelas, kembalikan object sebagai gantinya: { count, increment } sudah menjelaskan dirinya sendiri.

Tuple sebagai Parameter Fungsi

Rest parameter yang bertipe tuple menggambarkan seluruh daftar argumen, termasuk argumen opsional. Begitulah utility type bawaan Parameters<T> merepresentasikan parameter sebuah fungsi.

Melakukan spread tuple ke sebuah pemanggilan akan mengecek tipe setiap argumen berdasarkan posisinya, sesuatu yang tidak bisa dilakukan spread dari (string | number)[].

Tuple vs Array

Array (string | number)[]Tuple [string, number]
Panjangberapa sajatetap (atau dibatasi oleh elemen opsional dan rest)
Tipe x[0]string | numberstring
Tipe x[5]string | numbererror kompilasi TS2493
Tipe lengthnumber2
Urutan tipetidak dilacakdilacak
Nilai saat runtimearray JavaScriptarray JavaScript yang sama
Pemakaian umumdaftar item yang serupakelompok kecil yang tetap: pasangan, koordinat, [key, value], beberapa nilai kembalian

Tuple juga muncul di tipe bawaan. Object.entries(obj) mengembalikan [string, T][], dan sebuah Map dibangun dari tuple [key, value]:

Satu jebakan: tuple yang mutable tetap punya setiap method array, jadi pair.push(3) lolos kompilasi pada [string, number] dan diam-diam membuat array tiga elemen yang tipenya bilang dua. Mendeklarasikan tuple sebagai readonly menutup celah itu. Lalu, karena tipe dihapus saat kompilasi, data dari luar program (JSON, API) tidak dicek terhadap tipe tuple saat runtime: validasi panjang dan tipe elemennya sebelum memercayainya.

Variadic Tuple Type

Tipe tuple bisa melakukan spread tipe tuple lain, [...T, ...U]. Digabung dengan generic, ini memberi tipe pada fungsi yang menyambung atau menambahkan elemen di depan sambil mempertahankan setiap posisi:

Tipe di library juga mengandalkan inferensi tuple: Promise.all([fetchUser(), fetchPosts()]) resolve menjadi tuple dengan satu tipe untuk setiap promise input.

Pertanyaan yang sering diajukan

Apa itu tuple di TypeScript?

Tuple adalah tipe array dengan panjang tetap yang setiap posisinya punya tipe sendiri: [string, number] berarti tepat dua elemen, sebuah string lalu sebuah number. Saat runtime, tuple adalah array JavaScript biasa; panjangnya dan tipe di setiap posisi hanya dicek saat kompilasi.

Apa perbedaan tuple dan array di TypeScript?

Tipe array seperti (string | number)[] boleh punya panjang berapa saja dan setiap elemennya bertipe sama (union), jadi arr[0] adalah string | number. Tuple seperti [string, number] punya panjang yang diketahui, t[0] adalah string, t[1] adalah number, dan t[2] adalah error kompilasi.

Bagaimana cara mengembalikan tuple dari fungsi di TypeScript?

Beri anotasi tipe kembalian, function f(): [number, string], atau akhiri ekspresi return dengan as const, yang menghasilkan tuple readonly. Tanpa salah satunya, return [count, setCount] disimpulkan sebagai array berisi union, seperti (number | (() => void))[], dan destructuring menghasilkan tipe union.

Apa itu elemen tuple bernama?

Label pada posisi-posisinya, [name: string, age: number]. Label tidak mengubah tipe atau cara mengaksesnya (tetap t[0]), tetapi editor menampilkannya saat hover dan di petunjuk parameter fungsi yang parameternya bertipe tuple. Elemen opsional dan rest bisa dipakai dengan label: [x: number, y?: number], [head: string, ...rest: number[]].

Bisakah melakukan push ke tuple di TypeScript?

Pada tuple yang mutable, bisa: push lolos kompilasi, karena tuple mewarisi method array, walaupun itu merusak panjangnya yang tetap. Deklarasikan tuple sebagai readonly (atau buat dengan as const), maka push, pop dan assignment lewat index menjadi error kompilasi.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai