TypeScript adalah JavaScript yang diberi type: keterangan jenis data, misalnya teks, angka, atau fungsi, yang dicek sebelum kodenya dijalankan. Di React, file-nya berakhiran .tsx, dan yang paling sering diberi type adalah props, state, dan event. Bayangin formulir pendaftaran yang kolomnya sudah ditentukan: "Nama (teks)" dan "Umur (angka)". Kalau kamu menulis "tujuh belas" di kolom umur, petugas loket menolaknya sebelum formulirnya diproses. TypeScript adalah petugas loket itu: dia menolak di editor, sebelum aplikasinya jalan di browser.
🧪 Tebakan cepat:
ProfileCardmintaumurberupa angka, tapi kamu menulis<ProfileCard nama="Budi" umur="17" />lalu tetap menjalankannpm run dev. Apa yang tampil di browser: error merah, halaman kosong, atau "17 tahun"? Tebak dulu, jawabannya ada di bagian "Type hilang waktu dijalankan".
Props: tulis bentuknya sekali
type ProfileCardProps = {
nama: string
umur: number
isAdmin?: boolean // ? artinya boleh gak dikirim
onSapa?: () => void // fungsi tanpa argumen yang gak mengembalikan apa-apa
}
function ProfileCard({ nama, umur, isAdmin = false, onSapa }: ProfileCardProps) {
return (
<div onClick={onSapa}>
<h2 id="name">{nama}</h2>
<p id="age">{umur} tahun</p>
{isAdmin && <span>admin</span>}
</div>
)
}
<ProfileCard nama="Budi" umur={17} />
type ProfileCardProps = { ... }memberi nama pada bentuk props-nya.stringartinya teks,numberangka,booleantrue atau false.?diisAdmin?membuat prop itu opsional. Tanpa?, prop-nya wajib dikirim.() => voidadalah type sebuah fungsi.voidartinya fungsi itu gak mengembalikan apa-apa, cocok untuk event handler.: ProfileCardPropssesudah kurung kurawal destructuring memberi tahu TypeScript bentuk props yang diterima komponen ini.interface ProfileCardProps { nama: string; umur: number }juga boleh. Untuk props,typedaninterfacesama-sama jalan; pilih satu dan pakai konsisten.
Setiap kali komponen ini dipakai, TypeScript mencocokkan props yang dikirim dengan bentuk tadi. Ini yang dia bilang untuk empat pemakaian:
| Kode | Kata TypeScript |
|---|---|
<ProfileCard nama="Budi" umur={17} /> |
aman, gak ada error |
<ProfileCard nama="Budi" umur="17" /> |
Type 'string' is not assignable to type 'number'. (ts 2322) |
<ProfileCard nama="Budi" /> |
Property 'umur' is missing in type '{ nama: string; }' but required in type 'ProfileCardProps'. (ts 2741) |
<ProfileCard nama="Budi" umur={17} kota="Bandung" /> |
Property 'kota' does not exist on type 'IntrinsicAttributes & ProfileCardProps'. (penjelasan di bawah ts 2322) |
Error-nya muncul sebagai garis merah tepat di prop yang salah, jadi kamu tahu letaknya sebelum membuka browser.
State: biarkan ditebak, kecuali mulai dari null
type User = { nama: string }
const [count, setCount] = useState(0) // count: number
const [user, setUser] = useState<User | null>(null) // user: User | null
const [items, setItems] = useState<string[]>([]) // items: string[]
useState(0): TypeScript menebak (istilahnya infer) type dari nilai awal, jadicountbertypenumber.setCount("1")ditolak denganArgument of type 'string' is not assignable to parameter of type 'SetStateAction<number>'.useState<User | null>(null): type di dalam< >ditulis sendiri karena nilai awalnullgak cukup untuk menebak.|artinya "atau": isinyaUserataunull. Tanpa itu, type-nya cumanull, dansetUser({ nama: "Budi" })ditolak.useState<string[]>([]): array kosong juga gak cukup. Tanpa<string[]>, type-nyanever[], dansetItems(["a"])ditolak denganType 'string' is not assignable to type 'never'.
Event: pakai type milik React
function FormNama() {
const [nama, setNama] = useState("")
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setNama(e.target.value) // e.target adalah <input>, jadi .value pasti ada
}
return <input value={nama} onChange={handleChange} />
}
onChangedi<input>pakaiReact.ChangeEvent<HTMLInputElement>. Yang di dalam< >adalah elemen yang memicu event-nya.onClickdi<button>pakaiReact.MouseEvent<HTMLButtonElement>.onSubmitdi<form>pakaiReact.SubmitEvent<HTMLFormElement>. Kode lama menulisReact.FormEvent<HTMLFormElement>; sejak@types/react19.2 type itu ditandai deprecated, tapi masih jalan.- Handler yang ditulis langsung di JSX, misalnya
onChange={(e) => setNama(e.target.value)}, gak perlu type: TypeScript sudah tahuedari tempatnya.
children: React.ReactNode
type CardProps = {
judul: string
children: React.ReactNode // teks, angka, JSX, array, null: semua yang bisa dirender
}
React.ReactNode adalah type paling longgar untuk isi di antara tag pembuka dan penutup, jadi <Card judul="Profil"><p>Halo</p></Card> aman.
Type hilang waktu dijalankan
Browser gak mengerti type. Sebelum dijalankan, semua type dihapus. Ini sisa ProfileCard tadi:
function ProfileCard({ nama, umur, isAdmin = false, onSapa }) {
return (
<div onClick={onSapa}>
<h2 id="name">{nama}</h2>
<p id="age">{umur} tahun</p>
{isAdmin && <span>admin</span>}
</div>
)
}
type ProfileCardProps hilang seluruhnya, dan : ProfileCardProps juga. Waktu npm run dev, Vite cuma menghapus type tanpa mengeceknya, jadi umur="17" tetap tampil "17 tahun". Itu jawaban tebakannya: tampil normal, padahal TypeScript sudah protes. Yang mengecek adalah editor (garis merah) dan perintah tsc, yang di template Vite ikut jalan di npm run build ("build": "tsc -b && vite build"), jadi build-nya gagal sampai error-nya dibereskan. Data yang datang saat aplikasi jalan, misalnya hasil fetch, juga gak dicek oleh TypeScript.
⚠️ Jebakan yang sering ketemu
useState(null)tanpa type. Type-nya terkunci jadinull, dan setiapsetUser(...)dengan object ditolak. TulisuseState<User | null>(null).anydi mana-mana.(e: any)mematikan pengecekan, jadi salah ketik sepertie.target.valeulolos dan baru ketahuan di browser.- Type event yang salah.
React.MouseEvent<HTMLButtonElement>dipasang dionChangesebuah input ditolak denganType '(e: React.MouseEvent<HTMLButtonElement>) => void' is not assignable to type 'ChangeEventHandler<HTMLInputElement, HTMLInputElement>'. - Mengira pratinjau latihan mengecek type. Editor latihan menghapus type-nya seperti Vite waktu
npm run dev, tanpa mengeceknya. Jadiumur="17"tetap tampil di pratinjau. Yang menolaknya adalah garis merah di editor kode dantsc.
TL;DR: TypeScript mengecek type di editor sebelum kode jalan. Tulis bentuk props sekali dengan type (atau interface): string, number, ? untuk opsional, () => void untuk fungsi yang gak mengembalikan apa-apa, React.ReactNode untuk children. State ditebak dari nilai awal, kecuali mulai dari null atau []: tulis useState<User | null>(null) dan useState<string[]>([]). Event pakai type React: React.ChangeEvent<HTMLInputElement> untuk onChange, React.MouseEvent<HTMLButtonElement> untuk onClick, React.SubmitEvent<HTMLFormElement> untuk onSubmit. Semua type dihapus sebelum jalan, jadi error type ditangkap editor dan tsc, bukan browser.