Halo semuanya! Tim TestMace menerbitkan terjemahan lain artikel dari dunia pengembangan web. Kali ini untuk pemula! Selamat membaca.
Hancurkan tabir misteri dan kesalahpahaman atas sintaks <T>
dan akhirnya bertemanlah dengan itu

Mungkin, hanya pengembang Java yang berpengalaman atau bahasa yang sangat diketik lainnya yang tidak bisa melihat ketika mereka melihat generik dalam TypeScript. Sintaks dasarnya berbeda dari semua yang biasa kita lihat dalam JavaScript, jadi tidak mudah untuk langsung menebak apa fungsinya.
Saya ingin menunjukkan kepada Anda bahwa sebenarnya, semuanya jauh lebih sederhana daripada yang terlihat. Saya akan membuktikan bahwa jika Anda dapat mengimplementasikan fungsi dengan argumen dalam JavaScript, maka Anda dapat menggunakan obat generik tanpa usaha ekstra. Ayo pergi!
Generik dalam TypeScript
Dokumentasi TypeScript memberikan definisi berikut: "Generik adalah kemampuan untuk membuat komponen yang bekerja tidak hanya dengan satu, tetapi dengan beberapa tipe data."
Wow! Jadi, ide utamanya adalah bahwa obat generik memungkinkan kita untuk membuat beberapa komponen yang dapat digunakan kembali yang bekerja dengan berbagai jenis data yang dikirimkan kepada mereka. Tetapi bagaimana ini mungkin? Inilah yang saya pikirkan.
Generik dan tipe terkait satu sama lain, seperti nilai fungsi dan argumen. Ini adalah cara mengatakan komponen (fungsi, kelas atau antarmuka) jenis apa yang digunakan saat memanggil mereka, seperti saat panggilan, kami memberi tahu fungsi nilai yang digunakan sebagai argumen.
Yang terbaik untuk memahami ini menggunakan generik dari fungsi yang identik sebagai contoh. Fungsi identik adalah fungsi yang mengembalikan nilai argumen yang diteruskan ke sana. Dalam JavaScript, tampilannya akan seperti ini:
identity.js function identity (value) { return value; } console.log(identity(1))
Mari kita membuatnya bekerja dengan angka:
identitas function identity (value: Number) : Number { return value; } console.log(identity(1))
Ya, kami menambahkan jenis ke definisi fungsi yang identik, tetapi kami ingin agar lebih fleksibel dan berfungsi untuk nilai jenis apa pun, dan bukan hanya angka. Inilah gunanya obat generik. Mereka memungkinkan fungsi untuk mengambil nilai dari semua jenis data pada input dan, tergantung pada mereka, mengubah fungsi itu sendiri.
genericIdentity.ts function identity <T>(value: T) : T { return value; } console.log(identity<Number>(1))
Oh, sintaks <T>
yang aneh itu! Hentikan paniknya. Kami baru saja melewati tipe yang ingin kami gunakan untuk panggilan fungsi tertentu.

Lihatlah gambar di atas. Saat Anda memanggil identity<Number>(1)
, tipe Number
adalah argumen yang sama dengan 1. Ini diganti di mana saja untuk T
Suatu fungsi dapat mengambil beberapa jenis dengan cara yang sama seperti mengambil beberapa argumen.

Lihatlah panggilan fungsi. Sekarang sintaksis generik seharusnya tidak membuat Anda takut. T
dan U
hanyalah nama-nama variabel yang Anda tentukan sendiri. Ketika suatu fungsi dipanggil, tipe-tipe dengan mana fungsi ini akan bekerja diindikasikan sebagai gantinya .
Versi alternatif untuk memahami konsep generik adalah bahwa mereka mengubah fungsi tergantung pada tipe data yang ditentukan. Animasi di bawah ini menunjukkan bagaimana fungsi merekam dan hasil yang dikembalikan berubah ketika jenisnya diubah.

Seperti yang Anda lihat, fungsi menerima tipe apa pun, yang memungkinkan Anda membuat komponen yang dapat digunakan kembali dari berbagai jenis, seperti yang dijanjikan dalam dokumentasi.
Berikan perhatian khusus pada panggilan kedua ke console.log dalam animasi di atas - jenisnya tidak diteruskan. Dalam hal ini, TypeScript akan mencoba menghitung jenis dari data yang dikirimkan.
Kelas dan Antarmuka Umum
Anda sudah tahu bahwa obat generik hanyalah cara untuk mengirimkan tipe ke suatu komponen. Anda baru saja melihat bagaimana mereka bekerja dengan fungsi, dan saya punya kabar baik: mereka bekerja dengan cara yang sama dengan kelas dan antarmuka. Dalam hal ini, indikasi tipe mengikuti nama antarmuka atau kelas.
Lihatlah sebuah contoh dan cobalah untuk mencari tahu sendiri. Saya harap kamu berhasil.
genericClass.ts interface GenericInterface<U> { value: U getIdentity: () => U } class IdentityClass<T> implements GenericInterface<T> { value: T constructor(value: T) { this.value = value } getIdentity () : T { return this.value } } const myNumberClass = new IdentityClass<Number>(1) console.log(myNumberClass.getIdentity())
Jika kode tidak segera dipahami, cobalah melacak nilai-nilai type
dari atas ke kanan bawah ke panggilan fungsi. Prosedurnya adalah sebagai berikut:
- Sebuah instance baru dari kelas
IdentityClass
dibuat, dan tipe Number
dan nilai 1
diteruskan ke sana. - Di dalam kelas, nilai
T
diberikan tipe Number
. IdentityClass
mengimplementasikan GenericInterface<T>
, dan kami tahu bahwa T
adalah Number
, dan catatan seperti itu setara dengan GenericInterface<Number>
.- Dalam
GenericInterface
U
generik menjadi Number
. Dalam contoh ini, saya sengaja menggunakan nama variabel yang berbeda untuk menunjukkan bahwa nilai tipe naik rantai, dan nama variabel tidak memiliki arti.
Kasus penggunaan nyata: melampaui tipe primitif
Di semua sisipan kode di atas, tipe primitif seperti Number
dan string
digunakan. Sebagai contoh, ini yang paling banyak, tetapi dalam praktiknya, Anda tidak mungkin menggunakan obat generik untuk jenis primitif. Generik akan sangat berguna ketika bekerja dengan tipe atau kelas yang berubah-ubah yang membentuk pohon warisan.
Pertimbangkan contoh klasik warisan. Katakanlah kita memiliki kelas Car
, yang merupakan dasar dari kelas Truck
dan Vespa
. Kami menulis fungsi utilitas washCar, yang mengambil contoh generik dari Car
dan mengembalikannya.
car.ts class Car { label: string = 'Generic Car' numWheels: Number = 4 horn() { return "beep beep!" } } class Truck extends Car { label = 'Truck' numWheels = 18 } class Vespa extends Car { label = 'Vespa' numWheels = 2 } function washCar <T extends Car> (car: T) : T { console.log(`Received a ${car.label} in the car wash.`) console.log(`Cleaning all ${car.numWheels} tires.`) console.log('Beeping horn -', car.horn()) console.log('Returning your car now') return car } const myVespa = new Vespa() washCar<Vespa>(myVespa) const myTruck = new Truck() washCar<Truck>(myTruck)
Dengan washCar
fungsi washCar
bahwa T extends Car
, kami menunjukkan fungsi dan properti mana yang dapat kami gunakan di dalam fungsi ini. Generic juga memungkinkan Anda mengembalikan data dari tipe yang ditentukan alih-alih Car
biasa.
Hasil dari kode ini adalah:
Received a Vespa in the car wash. Cleaning all 2 tires. Beeping horn - beep beep! Returning your car now Received a Truck in the car wash. Cleaning all 18 tires. Beeping horn - beep beep! Returning your car now
Untuk meringkas
Saya harap saya membantu Anda berurusan dengan obat generik. Ingat, yang harus Anda lakukan hanyalah meneruskan nilai type
ke fungsi :)
Jika Anda ingin membaca lebih lanjut tentang obat generik, saya telah melampirkan beberapa tautan di bawah ini.
Apa yang harus dibaca :