Array di TypeScript
Anotasi array, array readonly, dan jebakan array kosong yang ter-infer any[].
Analogi: Rak Telur
Pernah lihat rak telur? Setiap lubang dirancang untuk satu telur, semuanya sama bentuk. Kamu tidak akan menaruh bola basket di rak telur. Array bertipe di TypeScript seperti rak telur: wadah untuk banyak item, tapi semuanya harus satu jenis.
JavaScript punya "rak" tanpa aturan: telur, bola basket, dan ikan bisa campur dalam satu array, dan kamu baru sadar masalahnya saat mengambil isinya. TypeScript memastikan sejak awal: rak telur hanya boleh diisi telur.
Kenapa Array Perlu Tipe?
Array adalah struktur data paling sering dipakai: daftar produk, daftar user, daftar transaksi. Tanpa tipe, setiap operasi array adalah judi. daftar.push(123) ke array nama? Lolos. total += harga di mana satu elemen ternyata string? Hasilnya "10050" bukan 150, dan kamu debugging setengah jam untuk menemukan satu elemen nakal.
Dengan string[], compiler menjaga dua hal: hanya string yang boleh masuk (lewat push dan kawan-kawan), dan setiap elemen yang keluar lewat akses indeks atau loop SUDAH PASTI string, jadi method seperti .toUpperCase() aman dipakai tanpa cek.
Contoh 1: Dua Cara Menulis Tipe Array
let angka: number[] = [1, 2, 3];
let nama: Array<string> = ["Budi", "Siti"]; // sama persis, gaya generik
// Loop dengan jaminan tipe per elemen
let total = 0;
for (const n of angka) {
total += n; // n: number, aman
}
const sapaan = nama.map((n) => `Halo ${n.toUpperCase()}`);
// n: string, jadi .toUpperCase() dijamin ada
console.log(sapaan); // ["Halo BUDI", "Halo SITI"]number[] adalah gaya yang paling umum. Array<string> identik secara tipe, biasanya dipakai kalau tipenya kompleks misalnya Array<{ nama: string }> agar lebih mudah dibaca.
Contoh 2: Array of Object, Kasus Dunia Nyata
Sedikit lebih kompleks: array berisi object, pola yang muncul di hampir setiap aplikasi:
type Barang = {
nama: string;
harga: number;
stok: number;
};
const keranjang: Barang[] = [
{ nama: "Kopi", harga: 18000, stok: 10 },
{ nama: "Gula", harga: 15000, stok: 5 },
];
function hitungTotalBelanja(items: Barang[]): number {
return items.reduce((total, item) => total + item.harga, 0);
}
console.log(hitungTotalBelanja(keranjang)); // 33000
// Salah ketik properti langsung ketahuan:
const mahal = keranjang.filter((b) => b.hagra > 16000);
// Error: Property 'hagra' does not exist on type 'Barang'.
// Did you mean 'harga'?Compiler bahkan menebak maksudmu ("Did you mean 'harga'?"). Tanpa tipe, b.hagra menghasilkan undefined, filternya diam-diam salah, dan total belanja jadi ngaco tanpa pesan error apa pun.
Contoh Nyata: Error Compiler Beraksi
Jebakan paling terkenal: array yang mulai kosong.
let daftar = []; // compiler menyimpulkan: any[]
daftar.push("apel");
daftar.push(123); // lolos! perlindungan hilang totalArray kosong tidak memberi petunjuk apa pun ke compiler, jadi ia menyerah dan memberi any[]. Solusinya anotasi eksplisit:
let daftar: string[] = [];
daftar.push("apel");
daftar.push(123);Error: Argument of type 'number' is not assignable to parameter of type 'string'.
Satu anotasi di awal mengunci seluruh masa depan array. Murah sekali harganya dibanding bug data campur aduk.
Kesalahan Umum Pemula
1. Membiarkan array kosong tanpa anotasi
// SALAH: ter-infer any[], semua bisa masuk
let nilai = [];
nilai.push(90);
nilai.push("seratus"); // lolos diam-diam
// BENAR: kunci tipenya sejak deklarasi
let nilai: number[] = [];
nilai.push(90);
nilai.push("seratus"); // Error, ketahuan langsung2. Mengira readonly melindungi saat runtime
// SALAH: berharap data aman dari modifikasi pihak luar
const HARI: readonly string[] = ["Senin", "Selasa"];
// Di runtime ini array biasa. Kode JS lain tetap bisa HARI.push("Rabu").
// BENAR: readonly = proteksi compile time untuk mencegah
// kesalahanmu sendiri, bukan tameng keamanan data.
const HARI: readonly string[] = ["Senin", "Selasa"];
HARI.push("Rabu");
// Error: Property 'push' does not exist on type 'readonly string[]'.
// Cocok untuk konstanta konfigurasi yang tidak boleh diubah tidak sengaja.3. Mengakses indeks di luar panjang array tanpa sadar
// SALAH: mengira akses indeks aman-aman saja
const angka: number[] = [1, 2, 3];
const keempat = angka[10]; // undefined saat runtime, tapi bertipe number!
// BENAR: sadari bahwa TypeScript tidak mengecek batas indeks.
// Selalu cek panjang dulu untuk akses yang tidak pasti:
const keempat = angka.length > 10 ? angka[10] : 0;
// Atau aktifkan noUncheckedIndexedAccess di tsconfig untuk proteksi ekstra.Catatan teknis:
readonly string[]hanya ada di level compile time. Setelah jadi.js, array-nya normal dan bisa dimutasi siapa pun. Kalau butuh array yang benar-benar tidak bisa diubah di runtime, pakaiObject.freeze().
Tantangan
Kunci keranjang belanja
Buat array keranjang: string[] yang diawali kosong, lalu push 3 nama barang. Setelah itu buat array KODE_PROMO: readonly string[] berisi 2 kode. Coba push ke KODE_PROMO dan amati error compilernya, lalu hapus baris yang error.
let keranjang: string[] = [];
// push 3 barang di sini
const KODE_PROMO: readonly string[] = ["HEMAT10", "GRATIS50"];
// coba KODE_PROMO.push("COBA") lalu hapus