Cheat Sheet: Jebakan Frustasi TypeScript

Ariska HidayatAriska Hidayat
3 min read

TypeScript memang powerful, tapi ada beberapa "jebakan" yang bisa bikin frustasi. Berikut daftarnya beserta solusinya:


1. Type Inference yang Menyesatkan

Masalah: TypeScript kadang infer tipe yang tidak diharapkan.

const arr = [1, 2, "3"]; // inferred as (number | string)[]

Solusi: Gunakan type annotation eksplisit.

const arr: number[] = [1, 2, 3]; // Error jika ada string

2. any yang Diam-diam Menyusup

Masalah: any menghilangkan type safety.

let data: any = "Hello";
data = 42; // No error, tapi bahaya!

Solusi: Hindari any, gunakan unknown atau type yang lebih spesifik.

let data: unknown = "Hello";
if (typeof data === "string") {
  console.log(data.toUpperCase()); // Safe
}

3. Optional vs Null/Undefined

Masalah: Bingung antara ?, null, dan undefined.

interface User {
  name?: string; // Optional property
}
const user: User = {};
console.log(user.name?.toUpperCase()); // OK
console.log(user.name.toUpperCase()); // Error: mungkin undefined

Solusi: Pahami perbedaannya:

  • ? = Properti opsional (bisa undefined).

  • null = Nilai eksplisit null.

  • undefined = Tidak ada nilai.


4. Type Narrowing yang Tidak Berfungsi

Masalah: TypeScript tidak selalu menyempitkan tipe dengan benar.

function isString(x: any): x is string {
  return typeof x === "string";
}
let value: string | number = "Hello";
if (isString(value)) {
  console.log(value.toUpperCase()); // OK
} else {
  console.log(value.toFixed(2)); // Error: mungkin string
}

Solusi: Gunakan type guards yang lebih eksplisit (typeof, instanceof, dll).


5. readonly yang Tidak Sepenuhnya Immutable

Masalah: readonly hanya berlaku di level terluar.

interface Config {
  readonly apiUrl: string;
  readonly endpoints: string[];
}
const config: Config = { apiUrl: "...", endpoints: ["/a", "/b"] };
config.endpoints.push("/c"); // Tidak error!

Solusi: Gunakan ReadonlyArray atau DeepReadonly (dengan utility type/library).

interface Config {
  readonly apiUrl: string;
  readonly endpoints: ReadonlyArray<string>;
}

6. Overloading Function yang Membingungkan

Masalah: Overload signature bisa rumit.

function greet(name: string): string;
function greet(age: number): string;
function greet(value: any): string {
  return typeof value === "string" ? `Hello, ${value}` : `Age: ${value}`;
}

Solusi: Gunakan union types jika memungkinkan.

function greet(value: string | number): string {
  return typeof value === "string" ? `Hello, ${value}` : `Age: ${value}`;
}

7. this Context yang Hilang

Masalah: this bisa berubah di callback.

class Button {
  onClick() {
    console.log("Clicked!");
  }
  addListener() {
    document.addEventListener("click", this.onClick); // `this` bukan instance Button!
  }
}

Solusi: Gunakan arrow function atau .bind(this).

class Button {
  onClick = () => {
    console.log("Clicked!");
  };
  addListener() {
    document.addEventListener("click", this.onClick); // Works!
  }
}

8. Generics yang Terlalu Kompleks

Masalah: Generics bisa bikin kode sulit dibaca.

function merge<T, U>(a: T, b: U): T & U {
  return { ...a, ...b };
}

Solusi: Gunakan default type atau batasi dengan constraints.

function merge<T extends object, U extends object>(a: T, b: U): T & U {
  return { ...a, ...b };
}

9. Module Resolution yang Membingungkan

Masalah: Import bisa error karena moduleResolution tidak sesuai.

// Error jika `moduleResolution: "node"` dan file tidak ada
import { something } from "./file.ts";

Solusi: Pahami konfigurasi tsconfig.json ("node", "classic", dll).


10. Strict Null Checks yang Ketat

Masalah: strictNullChecks bisa bikin banyak error.

let name: string;
name = null; // Error jika `strictNullChecks: true`

Solusi: Gunakan union type (string | null) atau optional chaining (?.).


Kesimpulan

  • Selalu aktifkan strict: true di tsconfig.json.

  • Hindari any, gunakan unknown atau type yang lebih spesifik.

  • Pahami perbedaan null, undefined, dan optional properties.

  • Gunakan type guards untuk narrowing.

  • Hati-hati dengan mutability (readonly, const, ReadonlyArray).

Semoga cheat sheet ini membantu menghindari jebakan TypeScript! ๐Ÿš€

0
Subscribe to my newsletter

Read articles from Ariska Hidayat directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Ariska Hidayat
Ariska Hidayat

I am an enthusiastic researcher and developer with a passion for using technology to innovate in business and education.