Tipe union dari generic dan non-generic dalam array TypeScript
Saat ini saya sedang bermain-main dengan TypeScript dan sedang bereksperimen dengan halaman Playground sambil mempertimbangkan untuk mengubah proyek yang ada menjadi TypeScript.
Saya menyelesaikan masalah yang sedang saya kerjakan, tetapi dalam prosesnya saya menemukan sesuatu yang belum sepenuhnya saya mengerti. Ini mengenai kelas antrian generik yang paling sederhana, yang sebagian ditunjukkan di sini.
class Queue<T> {
private store: T[] = [];
public enqueue(item: T) {
this.store.push(item);
}
}
const queue = new Queue<number>();
queue.enqueue(5); // works
queue.enqueue('six') // properly errors
Itu tentu saja bekerja dengan baik. Itu juga bekerja dengan baik jika penyimpanan pendukung diketik sebagai gabungan dari dua variabel tipe.
class Queue<T, U> {
private store: (T | U)[] = [];
public enqueue(item: T | U) {
this.store.push(item);
}
}
const queue = new Queue<number, boolean>();
queue.enqueue(5); // works
queue.enqueue(true); // works
queue.enqueue('six') // properly errors
Namun, ketika saya membuat store sebagai tipe union dari variabel tipe dan tipe konkret yang sudah ada, pemeriksaan tipe tidak berfungsi pada enqueue. (Empty adalah kelas singleton, dimaksudkan untuk meniru cara lama saya menunjukkan antrean kosong dengan mengembalikan objek EMPTY tertentu; saya tidak yakin apa cara terbaik untuk melakukannya, tetapi itu untuk pertanyaan lain.)
class Empty {
// implementation of singleton class
}
const EMPTY = Empty.instance;
class Queue<T> {
private store: (T | Empty)[] = [];
public enqueue(item: T | Empty) {
this.store.push(item);
}
}
const queue = new Queue<number>();
queue.enqueue(5); // works
queue.enqueue(EMPTY); // works
queue.enqueue('six') // also works, but it shouldn't
Memperkenalkan alias tipe untuk T | Empty tidak membantu, tidak mengherankan.
Sekarang dalam kenyataannya, ini bukan masalah bagi saya, karena implementasi antrian saya hanya menyimpan tipe T. Hanya dequeue saya yang memiliki tipe union dalam tandatangan metodenya, karena ia mengembalikan EMPTY jika penyimpanan kosong (dan itu bekerja dengan baik). Tapi saya tentu bisa melihat adanya tempat untuk array dari tipe union dengan parameter tipe dan tipe konkret, dan tanpa menyelidikinya lebih dalam, tampaknya ini adalah sesuatu yang pasti seharusnya mungkin dilakukan.
Apakah ini sesuatu yang tidak saya mengerti tentang bahasa ini, apakah saya melakukannya salah, atau ini hanya keterbatasan compiler?