Pertanyaan ini adalah analogon langsung ke cek tipe Kelas dengan TypeScript
Saya perlu mencari tahu pada saat runtime jika variabel jenis mengimplementasikan antarmuka. Ini kode saya:
interface A{
member:string;
}
var a:any={member:"foobar"};
if(a instanceof A) alert(a.member);
Jika Anda memasukkan kode ini di taman bermain naskah, baris terakhir akan ditandai sebagai kesalahan, "Nama A tidak ada dalam lingkup saat ini". Tapi itu tidak benar, namanya memang ada dalam ruang lingkup saat ini. Saya bahkan dapat mengubah deklarasi variabel menjadi var a:A={member:"foobar"};
tanpa keluhan dari editor. Setelah menjelajahi web dan menemukan pertanyaan lain pada SO saya mengubah antarmuka ke kelas tapi kemudian saya tidak bisa menggunakan objek literal untuk membuat instance.
Saya bertanya-tanya bagaimana tipe A bisa menghilang seperti itu tetapi melihat javascript yang dihasilkan menjelaskan masalahnya:
var a = {
member: "foobar"
};
if(a instanceof A) {
alert(a.member);
}
Tidak ada representasi A sebagai antarmuka, oleh karena itu tidak ada pemeriksaan tipe runtime yang dimungkinkan.
Saya mengerti bahwa javascript sebagai bahasa dinamis tidak memiliki konsep antarmuka. Apakah ada cara untuk mengetik cek antarmuka?
Pelengkapan otomatis taman bermain naskah itu mengungkapkan bahwa naskah bahkan menawarkan metode implements
. Bagaimana saya bisa menggunakannya?
Jawaban:
Anda dapat mencapai apa yang Anda inginkan tanpa
instanceof
kata kunci karena Anda dapat menulis penjaga tipe khusus sekarang:Banyak Anggota
Jika Anda perlu memeriksa banyak anggota untuk menentukan apakah suatu objek cocok dengan tipe Anda, Anda bisa menambahkan pembeda. Di bawah ini adalah contoh paling dasar, dan mengharuskan Anda untuk mengelola diskriminator Anda sendiri ... Anda harus masuk lebih dalam ke pola untuk memastikan Anda menghindari duplikat diskriminator.
sumber
isInstanceOfA(instantiatedB)
mengembalikan true, tetapi Anda inginisInstanceOfB(instantiatedA)
mengembalikan false. Agar yang terakhir terjadi, bukankah pembeda B tidak harus 'I-AM-A'?Dalam TypeScript 1.6, tipe penjaga yang ditentukan pengguna akan melakukan pekerjaan.
Dan seperti yang dikatakan Joe Yang: sejak TypeScript 2.0, Anda bahkan dapat mengambil keuntungan dari jenis tagged union.
Dan itu berhasil
switch
juga.sumber
object is type
danobject instanceof class
adalah bahwa, mengetikkan TypeScript adalah struktural, ia hanya peduli pada "bentuk" dan bukannya dari mana objek mendapatkan bentuk: objek biasa atau turunan dari sebuah kelas, itu tidak masalah.type
properti. Dalam hal ini berfungsi. Contoh itu tidak menunjukkan fakta ini.typescript 2.0 memperkenalkan serikat yang ditandai
Fitur Script 2.0
sumber
Bagaimana dengan Pengawal Tipe Buatan Pengguna? https://www.typescriptlang.org/docs/handbook/advanced-types.html
sumber
(pet as Fish).swim !== undefined;
berhasil.Sekarang mungkin, saya baru saja merilis versi yang ditingkatkan dari
TypeScript
kompiler yang menyediakan kemampuan refleksi penuh. Anda dapat membuat instance kelas dari objek metadata mereka, mengambil metadata dari konstruktor kelas dan memeriksa antarmuka / kelas saat runtime. Anda dapat memeriksanya di siniContoh penggunaan:
Di salah satu file naskah Anda, buat antarmuka dan kelas yang mengimplementasikannya seperti berikut:
sekarang mari kita cetak beberapa daftar antarmuka yang diimplementasikan.
kompilasi dengan reflec-ts dan luncurkan:
Lihat reflection.d.ts untuk
Interface
detail tipe-meta.PEMBARUAN: Anda dapat menemukan contoh lengkap di sini
sumber
implements
tetapi ingin mengenali komitmen Anda dan tidak ingin menjadi kejam :-)sama seperti di atas di mana penjaga yang ditentukan pengguna digunakan tetapi kali ini dengan predikat fungsi panah
sumber
Berikut opsi lain: modul ts-interface-builder menyediakan alat build-time yang mengubah antarmuka TypeScript menjadi deskriptor runtime, dan ts-interface-checker dapat memeriksa apakah suatu objek memuaskannya.
Sebagai contoh OP,
Anda pertama kali menjalankan
ts-interface-builder
yang menghasilkan file ringkas baru dengan deskriptor, katakanlahfoo-ti.ts
, yang dapat Anda gunakan seperti ini:Anda dapat membuat fungsi penjaga tipe satu-liner:
sumber
Saya ingin menunjukkan bahwa TypeScript tidak menyediakan mekanisme langsung untuk menguji secara dinamis apakah suatu objek mengimplementasikan antarmuka tertentu.
Sebaliknya, kode TypeScript dapat menggunakan teknik JavaScript untuk memeriksa apakah ada set anggota yang sesuai pada objek. Sebagai contoh:
sumber
for (element in obj) {}
) untuk memverifikasi bahwa dua objek memiliki elemen serupa dengan tipe yang sama.TypeGuards
sumber
Berdasarkan jawaban Fenton , inilah penerapan fungsi saya untuk memverifikasi apakah yang diberikan
object
memiliki kunciinterface
, baik sepenuhnya atau sebagian.Tergantung pada kasus penggunaan Anda, Anda mungkin juga perlu memeriksa jenis masing-masing properti antarmuka. Kode di bawah ini tidak melakukan itu.
Contoh penggunaan:
sumber
sumber
Karena tipe tidak diketahui pada saat run-time, saya menulis kode sebagai berikut untuk membandingkan objek yang tidak dikenal, bukan terhadap tipe, tetapi terhadap objek tipe yang dikenal:
Inilah kode (antarmuka-agnostik) yang saya gunakan untuk perbandingan mendalam:
Di bawah ini adalah contoh bagaimana saya menggunakannya.
Dalam contoh ini saya berharap JSON berisi array tupel, di mana elemen kedua adalah instance dari antarmuka yang disebut
User
(yang memiliki dua elemen opsional).Pengecekan typeScript akan memastikan bahwa objek sampel saya benar, maka fungsi assertTypeT memeriksa bahwa objek yang tidak diketahui (diambil dari JSON) cocok dengan objek sampel.
Anda bisa meminta cek seperti ini dalam implementasi tipe guard yang ditentukan pengguna.
sumber
Anda dapat memvalidasi tipe TypeScript saat runtime menggunakan tipe -ts-validate , seperti itu (memang membutuhkan plugin Babel):
sumber