value instanceof SomeClass adalah pemeriksaan JavaScript yang berjalan saat runtime: hasilnya true kalau SomeClass.prototype ada di prototype chain object tersebut, yang berarti object itu dibuat dengan new SomeClass (atau dengan sebuah subclass). TypeScript mempersempit tipe value menjadi SomeClass di dalam pemeriksaan itu.
Pakai instanceof untuk object yang dibuat dari class, dan typeof untuk tipe primitif. Di sini keduanya dibutuhkan: instanceof memisahkan Date, lalu typeof membagi sisanya.
Narrowing Class Buatanmu Sendiri
instanceof mempersempit tipe menjadi class tersebut di cabang true dan menghapusnya di cabang false, jadi union dari beberapa class bisa ditangani satu per satu.
Instance subclass juga lolos pemeriksaan untuk parent-nya: kalau Square extends Rect, maka new Square(2) instanceof Rect bernilai true. Uji class yang paling spesifik lebih dulu kalau cabang-cabangnya berbeda.
Subclass Error di catch
Pemakaian instanceof yang paling umum ada di dalam catch. Dengan strict, nilai yang ditangkap bertipe unknown (apa pun bisa di-throw), dan instanceof adalah cara untuk kembali ke error yang bertipe.
Output:
404: /missing.txt
TypeError: path must be absolute
class X extends Error bekerja dengan instanceof di setiap target yang didukung TypeScript 7 (ES2015 ke atas). Saran lama untuk memanggil Object.setPrototypeOf(this, X.prototype) di constructor berlaku untuk kode yang dikompilasi ke ES5, target yang sudah dihapus dari TypeScript 7.
instanceof Tidak Bekerja dengan Interface atau Type
Interface dan type alias hanya ada untuk compiler. Setelah kompilasi, tidak ada nilai User untuk dibandingkan, jadi TypeScript menolak pemeriksaan itu:
Compiler melaporkan index.ts(8,24): error TS2693: 'User' only refers to a type, but is being used as a value here. Ada dua cara memperbaikinya. Periksa bentuknya sendiri dengan type guard, yaitu fungsi yang mengembalikan value is User:
Atau, kalau kodemu sendiri yang membuat object-object ini, jadikan User sebuah class dan buat object-nya dengan new; dengan begitu instanceof bekerja. Halaman type guard membahas predicate dan assertion function secara detail.
Tipe yang Benar Bukan Berarti Instance yang Benar
TypeScript membandingkan tipe berdasarkan struktur: object literal dengan member yang sama seperti sebuah class bisa di-assign ke tipe class itu. instanceof tidak melihat struktur. Ia menelusuri prototype chain, dan object yang tidak pernah dibuat dengan new akan gagal walaupun compiler menerimanya sebagai tipe tersebut.
Baris terakhir itu penting. structuredClone, JSON.parse(JSON.stringify(...)), dan pesan antar-worker semuanya mengembalikan object biasa tanpa prototype class, walaupun tipe statisnya masih bisa menyatakan Point. Kalau instance class melewati batas seperti itu, bangun ulang object-nya (new Point(copy.x, copy.y)) sebelum mengandalkan instanceof atau method-nya.
instanceof dan Tipe Primitif
Tipe primitif (string, number, boolean...) bukan object dan tidak punya prototype chain, jadi "hi" instanceof String bernilai false. TypeScript menandai kesalahan ini kalau bisa: dengan nilai bertipe string di sisi kiri, instanceof menghasilkan error TS2358, The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. Pakai typeof untuk tipe primitif.
| Nilai | Pemeriksaan instanceof | Hasil |
|---|---|---|
new Date() | instanceof Date | true |
[1, 2] | instanceof Array | true (tetapi lebih baik Array.isArray) |
new TypeError("x") | instanceof Error | true (subclass) |
{ x: 1, y: 2 } | instanceof Point | false (tidak pernah dibuat dengan constructor) |
Object.create(null) | instanceof Object | false (tanpa prototype) |
"hi" | instanceof String | false (primitif) |
Nilai dari Realm Lain
instanceof membandingkan dengan satu object constructor tertentu. Kode yang berjalan di realm lain (sebuah iframe, atau context vm di Node) punya Array, Error, dan Date sendiri, jadi array yang dibuat di sana gagal pada instanceof Array di sini. Hal yang sama terjadi kalau dua salinan dari satu package npm sama-sama ada di node_modules: setiap salinan punya class sendiri, dan instance dari salinan yang satu gagal pada instanceof terhadap salinan yang lain. Untuk array, Array.isArray bekerja lintas realm. Untuk tipe buatanmu sendiri, memeriksa sebuah properti (dengan type guard, atau field kind) menghindari masalah ini sepenuhnya.
Pertanyaan yang sering diajukan
Bagaimana cara mengecek apakah sebuah object adalah instance dari suatu class di TypeScript?
Pakai value instanceof ClassName. Ini adalah pemeriksaan saat runtime (JavaScript biasa), dan TypeScript mempersempit tipe value menjadi ClassName di dalam if. Cara ini bekerja untuk class bawaan seperti Date, Map, dan Error, juga untuk class buatanmu sendiri.
Bisakah instanceof dipakai dengan interface di TypeScript?
Tidak. Interface dan type alias dihapus saat TypeScript dikompilasi menjadi JavaScript, jadi saat runtime tidak ada apa pun yang bisa dijadikan pembanding. x instanceof User dengan interface User menghasilkan error TS2693, "'User' only refers to a type, but is being used as a value here." Sebagai gantinya, periksa propertinya dengan fungsi type guard, atau jadikan User sebuah class kalau kamu sendiri yang membuat object-object itu.
Kenapa instanceof mengembalikan false untuk object yang tipenya benar?
Tipe TypeScript bersifat struktural: object literal { x: 1, y: 2 } bisa di-assign ke tipe class Point kalau member-nya sama. Tetapi instanceof memeriksa prototype chain, dan literal itu tidak pernah dibuat dengan new Point, jadi hasilnya false. Hal yang sama terjadi pada instance class yang melewati JSON, structuredClone, atau message channel, yang kembali sebagai object biasa.
Apakah instanceof bekerja dengan class Error buatan sendiri di TypeScript?
Ya, dengan target modern apa pun. class NotFound extends Error {}, lalu err instanceof NotFound bernilai true. Masalah lama ketika hasilnya false hanya terjadi pada output yang dikompilasi ke ES5, dan TypeScript 7 sudah tidak mendukung target ES5.
Kenapa "hello" instanceof String bernilai false?
String literal adalah tipe primitif, bukan object, jadi tidak punya prototype chain untuk diperiksa. instanceof String hanya bernilai true untuk object pembungkus yang dibuat dengan new String(). TypeScript menolak instanceof pada nilai bertipe string (TS2358); pakai typeof value === "string" untuk tipe primitif.