Di JavaScript, variabel bisa berisi nilai apa saja kapan saja — ini fleksibel tapi bisa menjadi sumber bug. TypeScript menyelesaikan ini dengan tipe data statis: kamu menentukan tipe saat mendeklarasikan variabel, dan compiler memastikan tipe itu tidak berubah. Jika kamu sudah familiar dengan tipe data JavaScript, di artikel ini kamu akan melihat bagaimana TypeScript memperketat dan memperkaya sistem tipe tersebut.
Tipe Primitif
string, number, boolean
let nama: string = "Andi Wijaya";
let umur: number = 25;
let aktif: boolean = true;
// TypeScript juga bisa menyimpulkan tipe dari nilai (type inference)
let kota = "Jakarta"; // TypeScript tahu ini string
let tahun = 2026; // TypeScript tahu ini number
let online = false; // TypeScript tahu ini boolean
// Mencoba mengubah tipe → error
kota = 42; // ❌ Error: Type 'number' is not assignable to type 'string'
tahun = true; // ❌ Error: Type 'boolean' is not assignable to type 'number'
Berbeda dengan JavaScript di mana let x = "halo"; x = 42; valid, TypeScript mengunci tipe setelah inisialisasi.
null dan undefined
let nama: string = "Budi";
nama = null; // ❌ Error dengan strict mode!
nama = undefined; // ❌ Error dengan strict mode!
// Jika nilainya bisa null, harus dideklarasikan eksplisit
let nama_opsional: string | null = null;
nama_opsional = "Budi"; // ✅ Valid
Dengan
"strict": true, TypeScript tidak mengizinkannull/undefineddimasukkan ke tipe lain kecuali dideklarasikan. Ini mencegahTypeError: Cannot read properties of null.
any dan unknown
any — Jalan Pintas yang Berbahaya
let data: any = "halo";
data = 42; // ✅ Valid
data = true; // ✅ Valid
data = { x: 1 }; // ✅ Valid — any mematikan semua pengecekan tipe!
// Ini tidak akan error meski jelas salah
data.metodeTidakAda(); // ✅ Tidak ada error... tapi akan crash saat runtime
Hindari
any! Menggunakananymenghilangkan semua manfaat TypeScript. Gunakan hanya sebagai langkah sementara saat migrasi dari JavaScript.
unknown — Alternatif yang Aman
let input: unknown = "halo";
input = 42; // ✅ Valid — bisa diisi nilai apapun
// Tapi tidak bisa digunakan tanpa pengecekan tipe
console.log(input.toUpperCase()); // ❌ Error: Object is of type 'unknown'
// Harus cek tipe dulu
if (typeof input === "string") {
console.log(input.toUpperCase()); // ✅ Valid setelah pengecekan
// Output: 42 (setelah input = 42, lalu input = "hello")
}
Aturan praktis: Gunakan unknown daripada any saat kamu tidak tahu tipenya — ini memaksamu untuk melakukan pengecekan sebelum menggunakan nilainya.
Array
// Dua cara penulisan yang ekuivalen
let angka: number[] = [1, 2, 3, 4, 5];
let nama_nama: Array<string> = ["Ali", "Budi", "Candra"];
angka.push(6); // ✅ Valid
angka.push("tujuh"); // ❌ Error: Argument of type 'string' is not assignable to type 'number'
// Array of objects
let produk: { nama: string; harga: number }[] = [
{ nama: "Laptop", harga: 15_000_000 },
{ nama: "Mouse", harga: 250_000 },
];
console.log(produk[0].nama);
// Output: Laptop
Tuple — Array dengan Tipe Tetap per Posisi
Tuple adalah array dengan jumlah elemen tetap dan tipe berbeda per posisi:
// Format: [tipe_index0, tipe_index1, ...]
let koordinat: [number, number] = [106.845, -6.209]; // [longitude, latitude]
let user_info: [string, number, boolean] = ["Rina", 22, true]; // [nama, umur, aktif]
koordinat[0] = 107.0; // ✅ Valid
koordinat[0] = "106"; // ❌ Error: Type 'string' is not assignable to type 'number'
koordinat[2] = 0; // ❌ Error: Tuple type '[number, number]' of length '2' has no element at index '2'
// Destructuring tuple
const [nama, umur, is_aktif] = user_info;
console.log(`${nama} (${umur}) — aktif: ${is_aktif}`);
// Output: Rina (22) — aktif: true
Tuple sering digunakan untuk nilai kembalian multiple dari fungsi — seperti useState di React yang mengembalikan [nilai, setSetter].
Enum — Sekumpulan Nilai Bernama
Enum memberikan nama yang bermakna pada sekumpulan nilai konstanta:
// Numeric enum (default)
enum Arah {
Utara, // = 0
Selatan, // = 1
Timur, // = 2
Barat // = 3
}
let tujuan: Arah = Arah.Utara;
console.log(tujuan); // Output: 0
console.log(Arah[tujuan]); // Output: Utara
// String enum — lebih mudah di-debug
enum Status {
Menunggu = "MENUNGGU",
Diproses = "DIPROSES",
Selesai = "SELESAI",
Dibatalkan = "DIBATALKAN"
}
let status_pesanan: Status = Status.Diproses;
console.log(status_pesanan);
// Output: DIPROSES (lebih mudah dibaca saat log!)
Gunakan string enum di proyek nyata — nilainya lebih mudah dibaca saat debugging atau logging.
Union Type — Satu Tipe atau Yang Lain
// Variabel bisa berisi string ATAU number
let id: string | number;
id = "USR-001"; // ✅ Valid
id = 42; // ✅ Valid
id = true; // ❌ Error: Type 'boolean' is not assignable to type 'string | number'
// Union type dalam parameter fungsi
function format_id(id: string | number): string {
if (typeof id === "number") {
return `#${id.toString().padStart(5, "0")}`; // "#00042"
}
return id.toUpperCase(); // "USR-001"
}
console.log(format_id(42)); // Output: #00042
console.log(format_id("usr-001")); // Output: USR-001
Literal Type — Nilai Spesifik sebagai Tipe
// Tipe yang hanya mengizinkan nilai tertentu
let arah: "utara" | "selatan" | "timur" | "barat";
arah = "utara"; // ✅ Valid
arah = "tengah"; // ❌ Error: Type '"tengah"' is not assignable
// Literal type numerik
let dadu: 1 | 2 | 3 | 4 | 5 | 6;
dadu = 3; // ✅ Valid
dadu = 7; // ❌ Error
// Kombinasi dengan type alias (akan dipelajari lebih lanjut di artikel Interface)
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE";
function request(url: string, method: HttpMethod): void {
console.log(`${method} ${url}`);
}
request("/api/users", "GET"); // ✅ Valid
request("/api/users", "PATCH"); // ❌ Error: Argument '"PATCH"' is not assignable
Type Inference — TypeScript Menyimpulkan Tipe
Kamu tidak selalu perlu menulis tipe secara eksplisit — TypeScript cukup pintar:
// TypeScript menyimpulkan tipe dari nilai
const pesan = "Halo Dunia"; // disimpulkan: string
const pi = 3.14159; // disimpulkan: number
const items = [1, 2, 3]; // disimpulkan: number[]
const user = { nama: "Ali", umur: 25 }; // disimpulkan: { nama: string; umur: number }
// Tipe return fungsi juga disimpulkan
function tambah(a: number, b: number) {
return a + b; // TypeScript tahu return type adalah number
}
const hasil = tambah(3, 4); // TypeScript tahu hasil adalah number
Kapan menulis tipe eksplisit? Ketika type inference tidak cukup jelas, untuk parameter fungsi, atau saat mendeklarasikan variabel tanpa nilai awal.
Pertanyaan yang Sering Diajukan
Apa perbedaan any dan unknown?
Keduanya bisa menerima nilai apa saja, tapi perbedaannya ada di penggunaan. any memungkinkan kamu melakukan operasi apa saja tanpa pengecekan — ini seperti mematikan TypeScript. unknown mengharuskan kamu melakukan pengecekan tipe (typeof, instanceof) sebelum menggunakan nilainya. Gunakan unknown saat tipe data tidak diketahui (misalnya dari API eksternal).
Kapan menggunakan tuple vs array biasa?
Gunakan tuple saat jumlah elemen tetap dan setiap posisi memiliki arti yang berbeda — misalnya [latitude, longitude], [nilai, setter] (seperti React’s useState), atau [berhasil, data]. Gunakan array saat semua elemen memiliki tipe yang sama dan jumlahnya bisa berubah.
Apakah type inference selalu benar?
Hampir selalu, tapi ada batasan. TypeScript menyimpulkan tipe paling spesifik dari nilai awal. Contoh: let x = [] disimpulkan sebagai never[] (array kosong), bukan number[]. Untuk kasus seperti ini, deklarasikan tipe eksplisit: let x: number[] = [].
Apa perbedaan number[] dan Array<number>?
Keduanya identik secara fungsionalitas — hanya perbedaan sintaks. number[] adalah “shorthand” yang lebih umum digunakan. Array<number> adalah versi generic yang lebih verbose. Pilih salah satu dan konsisten dalam satu proyek.
Kesimpulan
Ringkasan tipe data TypeScript:
| Tipe | Deskripsi | Contoh |
|---|---|---|
string | Teks | "halo" |
number | Angka (bulat & desimal) | 42, 3.14 |
boolean | Benar/salah | true, false |
any | Semua tipe (hindari!) | 42, "halo", {} |
unknown | Semua tipe (lebih aman) | Butuh pengecekan sebelum pakai |
T[] | Array bertipe | number[], string[] |
[T, U] | Tuple (posisi tetap) | [string, number] |
enum | Sekumpulan nilai bernama | Status.Aktif |
A | B | Union (salah satu) | string | number |
"a" | "b" | Literal type | "GET" | "POST" |
Artikel sebelumnya: Pengenalan TypeScript — hubungan TypeScript dengan JavaScript.
Langkah selanjutnya: Fungsi dengan Tipe di TypeScript — cara menambahkan tipe pada parameter dan return value fungsi.