Mengapa TypeScript mengizinkan ini?


Dalam TypeScript saya sedang membuat permintaan GET yang menghasilkan objek JS seperti ini:

// Note: The variable is not actually declared and hardcoded like this
// This is just to demonstrate what the received object looks like
let obj = {id: "1"};

Dan saya juga memiliki kelas berikut:

export class Test {
    constructor(public id: number) { }
}

Saya kemudian membuat instance baru dari kelas ini seperti ini:

let aClass = new Test(obj.id);

Dan untuk mengejutkan saya, instansnya dibuat dengan baik. Awalnya saya berpikir "Keren! Ini secara otomatis mencoba mengubah id menjadi angka!" tetapi ternyata tidak demikian, dan itu sedikit membingungkan saya.

console.log(typeof aClass.id);

Mengungkapkan bahwa id adalah tipe string. Saya keras kepala menolak untuk percaya itu, dan mencoba:

console.log(aClass.id += 12);

Dan seperti yang seharusnya saya harapkan pada titik ini, itu menambahkan "12" ke string.

Sekarang, pertanyaan saya adalah: mengapa ini terjadi dan mengapa tidak menimbulkan kesalahan?

Jawaban #1

Masalahnya, pengetikan Typescript diterapkan saat waktu kompilasi.

Data yang Anda ambil dari GET request Anda akan selalu diperlakukan sebagai any kecuali Anda melakukan sesuatu tentang itu. Karena TypeScript tidak memiliki cara untuk menentukan tipe data tersebut (bisa apa saja).

Yang bisa Anda lakukan adalah mengetik dengan kuat hasil pengembalian dari permintaan GET Anda. Kemudian TypeScript akan memberi Anda kesalahan. Tapi peringatan, itu tidak akan memberi Anda kesalahan jika permintaan GET tidak mengembalikan data yang diinginkan.

const data: {
  id: string,
} = GET();

// ...

Untuk validasi, ada beberapa plugin yang tersedia, seperti https://github.com/hapijs/joi

Saya menyarankan Anda untuk mendefinisikan interface untuk setiap permintaan GET, seperti:

interface GetUserR {
   users: {
     id: string,
     name: string,
   }[],
}

const users: GetUserR = await requester.GET('users');

Dengan cara ini Anda mendapatkan pelengkapan otomatis, kesalahan mudah terlihat, dan bersifat evolutif. Yang terbaik adalah jika backend Anda menghasilkan antarmuka ini jika Anda menangani front-end dan back-end.