Learn
← Previous Next →

Hari 12: Type Guards & Narrowing Lanjutan

60 min Last updated 09 Apr 2026

Type Guards

// typeof guard
function proses(x: string | number | boolean): string {
    if (typeof x === "string")  return x.toUpperCase();
    if (typeof x === "number")  return x.toFixed(2);
    return x.toString();
}

// instanceof guard
class Kucing { mengeong() { return "Meow!"; } }
class Anjing { menggonggong() { return "Guk!"; } }

function suara(hewan: Kucing | Anjing): string {
    if (hewan instanceof Kucing) return hewan.mengeong();
    return hewan.menggonggong();
}

// in operator guard
type Admin = { role: "admin"; permission: string[] };
type User  = { role: "user"; nama: string };

function cekRole(akun: Admin | User): void {
    if ("permission" in akun) console.log("Admin:", akun.permission);
    else console.log("User:", akun.nama);
}

Custom Type Predicate

// "is" keyword: parameter is Type
function isString(val: unknown): val is string {
    return typeof val === "string";
}

function isUser(obj: unknown): obj is User {
    return typeof obj === "object" && obj !== null
        && "role" in obj && (obj as any).role === "user";
}

const data: unknown = JSON.parse('{"role":"user","nama":"Budi"}');
if (isUser(data)) {
    console.log(data.nama); // TypeScript tahu data adalah User
}

💡 Notice: Discriminated union + switch + never = exhaustive check! TypeScript akan error jika ada case yang belum dihandle.

Assignment

Buat discriminated union: Circle {kind:"circle", r}, Rectangle {kind:"rect", w, h}, Triangle {kind:"tri", b, h}. Buat fungsi hitungLuas(shape) yang narrowing dengan switch. Hitung luas semua.

Expected output:

circle: 78.54
rect: 24.00
tri: 12.00
TS index.ts
Solution
Output