Kami menggunakan cookies untuk meningkatkan pengalaman Anda di website ini. Dengan melanjutkan, Anda menyetujui penggunaan cookies sesuai Kebijakan Privasi kami.
TypeScript sudah jadi standar di industri. Tapi banyak developer masih pakai TypeScript seperti JavaScript biasa. Ini 10 tips advanced yang benar-benar berguna di project nyata.
Muhamad Putra Aulia Hidayat
Setelah hampir 2 tahun TypeScript jadi standar wajib di hampir semua project JavaScript serius, masih banyak developer yang belum menggunakannya secara optimal. Ini tips-tips yang benar-benar berguna.
satisfies bukan Type Assertion// Buruk - as mematikan type checking
const config = {
theme: "dark",
port: 3000
} as AppConfig
// Lebih baik - satisfies tetap check tipe tapi pertahankan literal types
const config = {
theme: "dark",
port: 3000
} satisfies AppConfig
// Sekarang config.theme bertipe "dark" bukan string
// Buruk
interface ApiState {
loading: boolean
data?: User
error?: string
}
// Baik - setiap state eksplisit dan type-safe
type ApiState =
| { status: "idle" }
| { status: "loading" }
| { status: "success"; data: User }
| { status: "error"; error: string }
function render(state: ApiState) {
switch (state.status) {
case "success":
return state.data.name // TypeScript tahu data ada di sini
case "error":
return state.error // TypeScript tahu error ada di sini
}
}
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE"
type ApiRoute = "/users" | "/products" | "/orders"
type ApiEndpoint = `${HttpMethod} ${ApiRoute}`
// TypeScript akan autocomplete: "GET /users", "POST /products", dll
function callApi(endpoint: ApiEndpoint) { ... }
// Extract return type dari promise
type Awaited<T> = T extends Promise<infer R> ? R : T
// Extract parameter types
type FirstParam<T extends (...args: any) => any> =
T extends (first: infer F, ...rest: any) => any ? F : never
// Contoh penggunaan
async function fetchUser(): Promise<User> { ... }
type UserType = Awaited<ReturnType<typeof fetchUser>> // User
// Buat semua property opsional tapi hanya satu level
type PartialOne<T> = { [K in keyof T]?: T[K] }
// Buat semua property readonly dan required
type Frozen<T> = { readonly [K in keyof T]-?: T[K] }
// Buat type baru dengan rename key
type Getters<T> = {
[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K]
}
interface User { name: string; age: number }
type UserGetters = Getters<User>
// { getName: () => string; getAge: () => number }
// Tanpa const assertion
const ROLES = ["admin", "user", "moderator"]
// Tipe: string[]
// Dengan const assertion
const ROLES = ["admin", "user", "moderator"] as const
// Tipe: readonly ["admin", "user", "moderator"]
type Role = typeof ROLES[number]
// Tipe: "admin" | "user" | "moderator"
// Masalah: ID yang berbeda tapi sama-sama string
function getUser(userId: string) { ... }
function getProduct(productId: string) { ... }
// Tidak ada yang cegah: getUser(productId) -- bug!
// Solusi: Branded types
type UserId = string & { readonly __brand: "UserId" }
type ProductId = string & { readonly __brand: "ProductId" }
function createUserId(id: string): UserId {
return id as UserId
}
function getUser(userId: UserId) { ... }
// getUser(productId) sekarang error TypeScript!
type Shape = "circle" | "square" | "triangle"
function getArea(shape: Shape, size: number): number {
switch (shape) {
case "circle": return Math.PI * size ** 2
case "square": return size ** 2
case "triangle": return (Math.sqrt(3) / 4) * size ** 2
default:
// Kalau ada Shape baru yang belum di-handle, TypeScript error di sini
const _exhaustive: never = shape
throw new Error(`Unhandled shape: ${_exhaustive}`)
}
}
unknown bukan any// Buruk - any mematikan semua type checking
function processData(data: any) {
data.nonExistentMethod() // Tidak ada error, bug tersembunyi
}
// Baik - unknown paksa kamu validasi dulu
function processData(data: unknown) {
if (typeof data === "object" && data !== null && "name" in data) {
console.log((data as { name: string }).name)
}
}
Pastikan tsconfig.json kamu punya:
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
}
}
strict: true saja tidak cukup — noUncheckedIndexedAccess sangat berguna untuk mencegah bug saat akses array/object dengan index dinamis.
Semua tips di atas sudah kami terapkan di semua project Digital Uptime. Hasilnya: lebih sedikit bug di production dan onboarding developer baru jadi lebih mudah.
Tips teknologi & bisnis mingguan
Bergabung dengan 2,500+ subscriber yang mendapatkan insight teknologi, tutorial development, dan tips bisnis digital langsung ke inbox mereka setiap minggu.
Dapatkan tips & insight teknologi terbaru langsung ke inbox Anda.
© 2026 PT Digital Uptime Teknologi Informasi. Hak cipta dilindungi.