dasaranyunknownneverPemula4 mnt baca

any, unknown, dan never

Tiga tipe spesial: any yang berbahaya, unknown yang aman, never yang mustahil.

Analogi: Tiga Jalur di Bandara

Bayangkan bandara dengan tiga jalur pemeriksaan. Jalur pertama bertuliskan "lewat bebas, tidak diperiksa": cepat, tapi penyelundup juga lewat. Itu any. Jalur kedua memeriksa semua barang sebelum boleh lewat: agak lama, tapi aman. Itu unknown. Jalur ketiga adalah pintu yang tidak pernah dibuka untuk siapa pun: tidak ada yang bisa lewat, karena memang tidak ada yang boleh ada di sana. Itu never.

Ketiganya menangani "ketidakpastian", tapi dengan filosofi berlawanan. Memahami bedanya adalah pembeda antara kode TypeScript yang aman dan kode TypeScript yang cuma JavaScript berkedok.

Kenapa Tiga Tipe Ini Ada?

Dunia nyata itu berantakan. Data dari API, input user, hasil JSON.parse : semuanya datang tanpa jaminan bentuk. TypeScript butuh cara untuk berkata "aku belum tahu ini apa" tanpa berbohong bahwa ia tahu. any adalah jawaban lama yang terlalu permisif (mematikan pemeriksaan), unknown adalah jawaban modern yang jujur (memaksa pemeriksaan dulu), dan never adalah jawaban untuk "ini tidak mungkin terjadi" yang berguna untuk menangkap logika yang bolong.

Contoh 1: any Itu Menular

any berarti "jangan periksa apa pun tentang nilai ini". Sekali dipakai, ia menular ke semua yang menyentuhnya:

typescript
let data: any = "halo";
data = 42;              // boleh, tidak dicek
const hasil = data * 2; // hasil: any (menular!)
hasil.tidakAda();       // lolos compiler, meledak saat runtime

Satu any bisa meracuni seluruh rantai: variabel yang diturunkan darinya ikut menjadi any, dan compiler buta total di sepanjang rantai itu. Pakai any hanya sebagai jalan terakhir, misalnya saat migrasi kode JavaScript lama yang belum sempat diberi tipe.

Contoh 2: unknown Memaksa Jujur, never Menangkap yang Mustahil

unknown berarti "tidak tahu, jadi periksa dulu sebelum dipakai":

typescript
function prosesRespons(respons: string): number {
  const data: unknown = JSON.parse(respons);

  if (typeof data === "object" && data !== null && "total" in data) {
    const total = (data as { total: unknown }).total;
    if (typeof total === "number") {
      return total;
    }
  }
  throw new Error("respons tidak valid");
}

Setiap langkah dipersempit dulu lewat pengecekan. Repot? Sedikit. Tapi tidak ada lagi kejutan runtime dari data API yang bentuknya berubah diam-diam.

never untuk hal yang tidak mungkin terjadi, dan justru karena itu ia jadi alat pendeteksi logika bolong:

typescript
type Status = "sukses" | "gagal" | "pending";

function pesanStatus(s: Status): string {
  switch (s) {
    case "sukses": return "Berhasil!";
    case "gagal": return "Gagal, coba lagi.";
    case "pending": return "Mohon tunggu...";
    default:
      const sisa: never = s; // memastikan tidak ada kasus yang terlewat
      throw new Error(`Status tak dikenal: ${sisa}`);
  }
}

Trik const sisa: never = s disebut exhaustiveness check: kalau besok Status tambah varian baru misalnya "batal", compiler langsung protes di baris ini karena s tidak lagi never. Kamu dipaksa menangani varian baru itu.

Contoh Nyata: Error Compiler Beraksi

Dua error klasik dari dua tipe ini:

typescript
// Kasus 1: memakai unknown tanpa pemeriksaan
let data: unknown = "halo";
data.toUpperCase();
Error: 'data' is of type 'unknown'.
typescript
// Kasus 2: memaksa nilai masuk ke never
function mustahil(): never {
  throw new Error("selalu gagal");
}

const x: never = "ada";
Error: Type 'string' is not assignable to type 'never'.

Error pertama adalah unknown yang menjalankan tugasnya: melindungimu dari asumsi. Error kedua menunjukkan sifat never: tidak ada nilai apa pun yang boleh menempatinya, karena ia melambangkan ketiadaan.

Kesalahan Umum Pemula

1. Memakai any sebagai default saat malas mikir tipe

typescript
// SALAH: checklist dimatikan, bug kembali seperti di JavaScript
function jumlahkan(a: any, b: any): any {
  return a + b;
}
jumlahkan("1", 2); // "12", tidak ada yang protes

// BENAR: tergoda pakai any? Pakai unknown + narrow
function jumlahkan(a: unknown, b: unknown): number {
  if (typeof a !== "number" || typeof b !== "number") {
    throw new Error("keduanya harus number");
  }
  return a + b;
}

2. Mem-bypass unknown dengan as tanpa pengecekan

typescript
// SALAH: assertion buta, sama berbahayanya dengan any
function ambilNama(data: unknown): string {
  return (data as { nama: string }).nama; // kalau data bukan object? Meledak.
}

// BENAR: persempit dulu dengan pengecekan nyata
function ambilNama(data: unknown): string {
  if (typeof data === "object" && data !== null && "nama" in data) {
    const nama = (data as { nama: unknown }).nama;
    if (typeof nama === "string") return nama;
  }
  throw new Error("data tidak punya nama string");
}

3. Mengira never sama dengan void

typescript
// SALAH: fungsi yang return undefined dikira never
function logPesan(pesan: string): never {
  console.log(pesan); // Error: Type 'void' is not assignable to type 'never'.
}

// BENAR: void = tidak mengembalikan nilai (tapi selesai normal).
// never = tidak pernah selesai normal (throw atau infinite loop).
function logPesan(pesan: string): void {
  console.log(pesan);
}

function gagalTotal(pesan: string): never {
  throw new Error(pesan); // tidak pernah kembali
}

Catatan teknis: Di strict mode, parameter fungsi tanpa anotasi menjadi implicit any dan error (noImplicitAny). Ini fitur, bukan bug: compiler memaksamu sadar setiap kali type safety dimatikan, jadi tidak ada any yang menyelinap diam-diam.

Tantangan

Amankan any

Fungsi berikut memakai any dan berbahaya. Refactor agar memakai unknown + pengecekan typeof, sehingga hanya string yang diproses dan tipe lain ditolak dengan pesan error yang jelas.

typescript
function cetakPanjang(data: any): number {
  return data.length;
}

console.log(cetakPanjang("halo")); // 4

Kuis Bab

Uji pemahamanmu: Fondasi TypeScript

Jawab 5 soal berikut, lalu tekan "Periksa Jawaban".

1.Apa keuntungan utama TypeScript dibanding JavaScript?

2.Apa fungsi file tsconfig.json?

3.Apa beda null dan undefined di TypeScript strict mode?

4.Kapan sebaiknya memakai unknown dibanding any?

5.Apa itu type inference?