Menu

Object Type di TypeScript: Property Opsional dan Readonly

Cara memberi tipe pada object di TypeScript: object type inline, property opsional dengan ?, property readonly, object bersarang, method, excess property check, dan perbedaan object, {} dan Object.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

Object type di TypeScript mendaftar property yang dimiliki sebuah object beserta tipe masing-masing: { name: string; age: number }. Tambahkan ? untuk membuat property opsional dan readonly supaya property tidak bisa di-assign ulang. Tulis tipenya inline, atau beri nama dengan type atau interface supaya bisa dipakai ulang.

Property dipisahkan dengan ; atau , (keduanya bisa, ; adalah gaya yang umum), dan baris baru saja sudah cukup. Tipe inline cocok untuk parameter yang hanya dipakai sekali; untuk apa pun yang dipakai dua kali, beri nama.

// Inline, in a parameter
function area(rect: { width: number; height: number }): number {
    return rect.width * rect.height;
}

// Named with a type alias
type Rect = { width: number; height: number };

// Named with an interface (the same shape)
interface RectShape {
    width: number;
    height: number;
}

type dan interface sama baiknya untuk menggambarkan bentuk object. Perbedaannya (declaration merging, union) dibahas di halaman interface vs type.

Mengakses property yang tidak dideklarasikan tipenya adalah error kompilasi: point.z menghasilkan TS2339, Property 'z' does not exist on type '{ x: number; y: number; }'.

Property Opsional

Tanda ? setelah nama membuat property itu boleh tidak disertakan. Membaca property opsional menghasilkan T | undefined, jadi TypeScript memaksamu menangani kasus kosong sebelum memakainya.

Memanggil method pada property opsional tanpa pengecekan adalah error: p.nickname.toUpperCase() gagal dengan TS18048, 'p.nickname' is possibly 'undefined'. Pakai optional chaining (p.nickname?.toUpperCase()) kalau undefined adalah hasil yang bisa diterima.

prop?: T dan prop: T | undefined tidak sama. Yang pertama mengizinkan key-nya tidak ada; yang kedua mewajibkan key-nya ada, walaupun nilainya boleh undefined:

Property Readonly

readonly mencegah property di-assign ulang setelah object dibuat. Ini hanya pengecekan saat kompilasi, dan sifatnya dangkal: object atau array yang tersimpan di property readonly tetap bisa diubah isinya.

Output-nya menunjukkan kedua batasan itu: id benar-benar berubah saat runtime (hanya compiler yang tahu property itu readonly), dan array di dalamnya ikut diubah. Untuk array readonly, pakai readonly string[]; untuk membuat semua property readonly sekaligus, pakai Readonly<Order>.

Excess Property Check

Saat kamu meng-assign object literal langsung ke variabel bertipe atau langsung mengirimnya ke parameter bertipe, TypeScript menolak setiap property yang tidak dideklarasikan tipenya. Property tambahan di literal yang baru dibuat hampir selalu berarti salah ketik.

index.ts(8,8): error TS2561: Object literal may only specify known properties, but 'colour' does not exist in type 'Options'. Did you mean to write 'color'?

Kodenya TS2561 karena compiler menemukan nama yang mirip; property tambahan tanpa nama yang mirip menghasilkan TS2353, Object literal may only specify known properties, and 'z' does not exist in type 'Point'. Tanpa pengecekan ini, salah ketik itu akan lolos kompilasi, color akan bernilai undefined, dan program diam-diam menggambar dengan warna hitam. Pengecekan ini hanya berlaku untuk literal yang baru dibuat. Object yang sudah tersimpan di variabel boleh membawa property tambahan, karena sistem tipe TypeScript bersifat struktural: sebuah nilai cocok dengan suatu tipe kalau ia punya setidaknya property yang diwajibkan.

Object Bersarang dan Method

Object type bisa bersarang, dan bisa menggambarkan method dengan sintaks method atau dengan property bertipe fungsi.

Untuk bentuk yang dalam atau dipakai ulang, beri nama tipe bagian dalamnya (type Address = { ... }) lalu rujuk tipe itu, atau ambil dari tipe luarnya dengan indexed access, Company["address"], seperti di baris terakhir.

object vs {} vs Object

Tiga tipe ini terdengar mirip, tetapi artinya berbeda:

TipeMenerimaMenolak
objectapa pun yang bukan primitif: {}, [], fungsi, instance class5, "a", true, null, undefined
{}nilai apa pun selain null dan undefined, termasuk primitifnull, undefined
Objectsama dengan {}, ditambah pengecekan bahwa member bawaan seperti toString tetap bertipe kompatibelnull, undefined
{ x: number }nilai apa pun yang punya x bertipe numbernilai tanpa x

{} tidak berarti "object kosong"; artinya "bukan null atau undefined". Untuk menerima object apa pun dengan key yang tidak diketahui, pakai Record<string, unknown>; untuk pemetaan key ke nilai, pakai index signature atau Record seperti yang ditunjukkan di halaman dictionary. Hampir selalu, bentuk yang spesifik lebih baik daripada ketiganya.

Pertanyaan yang sering diajukan

Bagaimana cara mendefinisikan object type di TypeScript?

Tulis property dan tipenya di dalam kurung kurawal: { name: string; age: number }. Kamu bisa menulisnya langsung di anotasi, atau memberinya nama dengan type User = { ... } atau interface User { ... } lalu memakainya ulang. Pisahkan property dengan ; atau ,.

Bagaimana cara membuat property opsional di TypeScript?

Taruh ? setelah nama property: { name: string; nickname?: string }. Object itu boleh tidak menyertakan nickname, dan membacanya menghasilkan string | undefined, jadi kamu harus mengeceknya atau memberi nilai default (user.nickname ?? user.name) sebelum memakainya sebagai string.

Apa perbedaan prop?: string dan prop: string | undefined?

Dengan prop?: string, key-nya boleh tidak ada sama sekali. Dengan prop: string | undefined, key-nya wajib ada, walaupun nilainya boleh undefined, sehingga {} menjadi error kompilasi. Membaca keduanya menghasilkan string | undefined.

Apa perbedaan object, {} dan Object di TypeScript?

object berarti nilai apa pun yang bukan primitif (object, array, fungsi) dan menolak 5 atau "a". {} berarti nilai apa pun selain null dan undefined, termasuk primitif. Object hampir sama dengan {}, tetapi juga memeriksa bahwa method bawaan seperti toString tetap bertipe kompatibel. Pakai object, atau lebih baik lagi bentuk yang spesifik, daripada {} atau Object.

Kenapa TypeScript mengeluh bahwa object literal hanya boleh berisi property yang dikenal?

Itu adalah excess property check: error TS2353, atau TS2561 kalau compiler bisa menyarankan property yang kemungkinan kamu maksud. Saat kamu meng-assign object literal yang baru dibuat langsung ke variabel atau parameter bertipe, setiap property yang tidak dideklarasikan tipenya akan ditandai, karena biasanya itu salah ketik. Meng-assign object yang tersimpan di variabel lain melewati pengecekan ini, karena structural typing mengizinkan property tambahan.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai