assertionascastingMahir3 mnt baca

Type Assertion dengan as

Memberi tahu compiler tipe yang kamu yakini: as, dan risikonya.

as: "percayalah, saya lebih tahu"

Type assertion adalah kamu berkata ke compiler: "sudahlah, saya yang tahu tipe aslinya". Sintaksnya nilai as Tipe.

typescript
let data: unknown = "halo";
let s = data as string; // "saya yakin ini string"
s.toUpperCase(); // compiler nurut

Pahami satu hal yang fundamental: as tidak mengubah nilai dan tidak melakukan konversi apa pun. Tidak ada runtime check, tidak ada transformasi data. Ia hanya mengganti kacamata compiler saat melihat nilai itu. Nilai di memorinya tetap sama persis seperti sebelum assertion.

Kapan as masuk akal: compiler buta, kamu tidak

Ada situasi di mana KAMU punya informasi yang mustahil diketahui compiler dari kode:

typescript
// Kamu yang menulis HTML-nya, kamu tahu #nama itu <input>.
const input = document.getElementById("nama") as HTMLInputElement;
input.value; // tanpa as, error: getElementById me-return HTMLElement | null

Kasus sah lainnya: hasil JSON.parse yang strukturnya kamu kontrol penuh, atau interop dengan library JavaScript lama yang tipenya any. Polanya selalu sama: informasi tambahan datang dari luar kode yang bisa dilihat compiler, dan kamu adalah satu-satunya sumber informasi itu.

SALAH: as untuk data yang belum divalidasi

Ini pola paling berbahaya dan paling sering ditemui di codebase nyata:

typescript
interface User { id: number; nama: string }

const res = await fetch("/api/user/1");
const user = (await res.json()) as User; // SALAH tapi lolos compiler
console.log(user.nama.toUpperCase());

Kalau API ternyata me-return { error: "not found" }, maka user.nama itu undefined, dan .toUpperCase() meledak saat runtime. Compiler diam saja, karena kamu yang menyuruh dia percaya. Bandingkan dengan yang benar:

typescript
const raw: unknown = await res.json();
if (adalahUser(raw)) {            // type predicate, ada bukti runtime
  console.log(raw.nama.toUpperCase()); // terverifikasi, aman
} else {
  console.log("data user rusak, tampilkan pesan error");
}

Bedanya satu kata kunci: verifikasi. as hanya mengklaim, guard membuktikan dengan pengecekan yang benar-benar dieksekusi.

Error compiler nyata: as pun ada batasnya

Compiler tidak membiarkan assertion yang jelas-jelas ngawur antar tipe yang tidak berhubungan:

typescript
const nama = "budi";
const angka = nama as number;
text
error TS2352: Conversion of type 'string' to type 'number' may be a mistake
  because neither type sufficiently overlaps with the other.

Tapi ada celah yang sering disalahgunakan: lewat unknown dulu, semuanya bisa lolos.

typescript
const x = "halo" as unknown as number; // lolos compiler!
x.toFixed(2); // runtime: x.toFixed is not a function. Crash.

Double assertion as unknown as T pada dasarnya menonaktifkan type checker untuk satu baris. Kalau kamu menemukannya saat code review, anggap itu bendera merah yang wajib ditanya alasannya.

Kapan dipakai di project nyata

  • Kode DOM yang kamu tulis sendiri: getElementById, querySelector, event.target di form yang strukturnya kamu kendalikan. Idealnya setelah null check.
  • Migrasi bertahap JS ke TS: file lama bertipe any di mana-mana, as dipakai sementara sambil tipe yang benar ditulis. Harus dicatat sebagai utang, bukan solusi permanen.
  • Test: bikin objek parsial lalu as ke tipe penuh biar tidak perlu mengisi 20 field yang tidak relevan dengan test itu. Di test, risikonya terkendali.

Catatan teknis: Aturan emasnya sederhana: as hanya untuk kasus di mana kamu punya info yang tidak dimiliki compiler (struktur DOM yang kamu tulis, kontrak internal antar modul). Untuk data dari luar (API, JSON, form, query string, localStorage), JANGAN pakai as: validasi dengan type guard, assertion function, atau Zod. Makin sedikit as di codebase, makin bisa dipercaya type safety-nya.

Tantangan

Assertion yang jujur

Diberikan const el = document.getElementById("email") (tipe HTMLElement | null). Tulis assertion yang benar ke HTMLInputElement SETELAH memastikan tidak null (pakai if atau pastikanAda). Jelaskan di komentar kenapa assertion di sini aman.

typescript
const el = document.getElementById("email");

// 1. pastikan tidak null dulu
// 2. assertion ke HTMLInputElement
// 3. akses .value