Cheat Sheet: Jebakan Frustasi TypeScript


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 (bisaundefined
).null
= Nilai eksplisitnull
.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
ditsconfig.json
.Hindari
any
, gunakanunknown
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! ๐
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.