Saya menulis kode ini
interface Foo {
abcdef: number;
}
let x: Foo | string;
if (x instanceof Foo) {
// ...
}
Tapi TypeScript memberi saya kesalahan ini:
'Foo' only refers to a type, but is being used as a value here.
Mengapa ini terjadi? Saya pikir itu instanceof
dapat memeriksa apakah nilai saya memiliki tipe tertentu, tetapi TypeScript tampaknya tidak seperti ini.
javascript
typescript
instanceof
Daniel Rosenwasser
sumber
sumber
Foo | string
.Jawaban:
Apa yang sedang terjadi
Masalahnya adalah itu
instanceof
adalah konstruksi dari JavaScript, dan dalam JavaScript,instanceof
mengharapkan nilai untuk operan sisi kanan. Secara khusus, dix instanceof Foo
JavaScript akan melakukan pemeriksaan waktu proses untuk melihat apakahFoo.prototype
ada di mana saja dalam rantai prototipex
.Namun, dalam TypeScript,
interface
s tidak memiliki emit . Itu berarti bahwa baikFoo
atauFoo.prototype
ada pada saat runtime, jadi kode ini pasti akan gagal.TypeScript mencoba memberi tahu Anda bahwa ini tidak akan pernah berhasil.
Foo
hanyalah sebuah tipe, itu bukanlah nilai sama sekali!"Apa yang bisa saya lakukan sebagai gantinya
instanceof
?"Anda dapat melihat pelindung tipe dan pelindung tipe yang ditentukan pengguna .
"Tapi bagaimana jika aku baru saja beralih dari a
interface
ke aclass
?"Anda mungkin tergoda untuk beralih dari a
interface
ke aclass
, tetapi Anda harus menyadari bahwa dalam sistem tipe struktural TypeScript (di mana hal-hal terutama berbasis bentuk ), Anda dapat menghasilkan objek apa pun yang memiliki bentuk yang sama dengan kelas yang diberikan:class C { a: number = 10; b: boolean = true; c: string = "hello"; } let x = new C() let y = { a: 10, b: true, c: "hello", } // Works! x = y; y = x;
Dalam hal ini, Anda memiliki
x
dany
yang memiliki tipe yang sama, tetapi jika Anda mencoba menggunakaninstanceof
salah satu, Anda akan mendapatkan hasil yang berlawanan di sisi lain. Jadiinstanceof
tidak akan benar-benar memberitahu Anda banyak tentang jenis jika Anda mengambil keuntungan dari jenis struktural dalam naskah.sumber
instanceof
bekerja dengan kelas, bukan antarmuka. Pemikiran itu perlu ditekankan.Untuk melakukan pengecekan tipe saat runtime dengan sebuah antarmuka menggunakan pelindung tipe , jika antarmuka yang ingin Anda periksa memiliki properti / fungsi yang berbeda .
Contoh
let pet = getSmallPet(); if ((pet as Fish).swim) { (pet as Fish).swim(); } else if ((pet as Bird).fly) { (pet as Bird).fly(); }
sumber
Duck
, Anda jenis penjaga itu menjadiFish
, tetapi masih ada pengecualian runtime saat Anda memanggilswim()
. Sarankan Anda membuat 1 tingkat antarmuka umum (misalnyaSwimmable
) dan memindahkanswim()
fungsi Anda ke sana, kemudian tipe penjaga masih terlihat bagus((pet as Swimmable).swim
.'swim' in pet
kondisi. Ini akan mempersempit ke subset yang memiliki telahswim
didefinisikan (ex:Fish | Mammal
)Daniel Rosenwasser mungkin benar dan keren, tetapi saya ingin mengubah jawabannya. Sangat mungkin untuk memeriksa contoh x, lihat cuplikan kode.
Tetapi sama mudahnya untuk menetapkan x = y. Sekarang x tidak akan menjadi turunan dari C karena y hanya berbentuk C.
class C { a: number = 10; b: boolean = true; c: string = "hello"; } let x = new C() let y = { a: 10, b: true, c: "hello", } console.log('x is C? ' + (x instanceof C)) // return true console.log('y is C? ' + (y instanceof C)) // return false
sumber
Periksa apakah file ur dalam jenis yang tepat. Tag tidak diperbolehkan di file js, tapi diperbolehkan di jsx
sumber