TypeScript - Generic Constraints: Unleashing the Power of Flexible Types
Hai there, future TypeScript magicians! Hari ini, kita akan mengembara ke dunia yang menarik dari Generic Constraints. Jangan khawatir jika Anda baru belajar pemrograman - saya akan menjadi panduan yang ramah, dan kita akan menangani topik ini secara berangsur-angsur. Pada akhir panduan ini, Anda akan bisa membatasi generik seperti seorang pro!
What Are Generic Constraints?
Sebelum kita masuk ke detailnya, mari mulai dengan analogi sederhana. Bayangkan Anda memiliki kotak ajaib yang dapat menampung jenis item apa saja. Itu sebenarnya apa yang dimaksudkan oleh generic di TypeScript - sebuah wadah fleksibel untuk jenis-jenis yang berbeda. Sekarang, bagaimana jika kita ingin menetapkan beberapa aturan tentang apa saja yang dapat dimasukkan ke dalam kotak itu? Itu adalah tempat generic constraints masuk ke dalam!
Generic constraints memungkinkan kita untuk membatasi jenis yang dapat digunakan dengan generik kita. Itu seperti memberi label pada kotak ajaib kita yang mengatakan, "Hanya objek dengan properti 'length' yang diizinkan!"
Problem Examples: Why Do We Need Generic Constraints?
Marilah kita lihat beberapa contoh di mana generic constraints dapat menyelamatkan hari:
Example 1: The Mysterious Length Property
function getLength<T>(item: T): number {
return item.length; // Error: Property 'length' does not exist on type 'T'
}
Ups! TypeScript memberikan kita kesalahan. Mengapa? Karena tidak semua jenis memiliki properti length
. Apa bila kita mengirimkan bilangan ke fungsi ini? Bilangan tidak memiliki panjang!
Example 2: The Confusing Comparison
function compareValues<T>(value1: T, value2: T): boolean {
return value1 > value2; // Error: Operator '>' cannot be applied to types 'T' and 'T'
}
Kesalahan lagi! TypeScript tidak tahu jika T
dapat dibandingkan menggunakan >
. Apa bila kita mengirimkan string? Atau objek kompleks?
Contoh ini menunjukkan kepada kita mengapa kita butuh generic constraints. Mereka membantu kita menulis kode yang lebih tepat dan bebas kesalahan.
How Generic Constraints Work in TypeScript
Sekarang, mari kita lihat bagaimana kita dapat menggunakan generic constraints untuk memecahkan masalah kita:
The Magical extends
Keyword
Untuk menambahkan batasan, kita menggunakan kata kunci extends
. Itu seperti memberitahu TypeScript, "Hey, jenis ini harus memiliki setidaknya properti atau kemampuan ini!"
Marilah kita perbaiki fungsi getLength
:
interface Lengthwise {
length: number;
}
function getLength<T extends Lengthwise>(item: T): number {
return item.length; // Tidak ada kesalahan lagi!
}
Sekarang, mari kitauraikan ini:
- Kita definisikan sebuah interface
Lengthwise
yang memiliki propertilength
. - Kita gunakan
<T extends Lengthwise>
untuk mengatakan "T harus memiliki setidaknya apa yang Lengthwise punya". - Sekarang TypeScript tahu bahwa apa pun
T
itu, ia pasti akan memiliki propertilength
!
Marilah kita coba:
console.log(getLength("Hello")); // Bekerja! String memiliki panjang
console.log(getLength([1, 2, 3])); // Bekerja! Array memiliki panjang
console.log(getLength(123)); // Kesalahan! Bilangan tidak memiliki panjang
Apakah itu menakjubkan? Kita telah berhasil membatasi generik kita!
Using Type Parameters in Generic Constraints
kadang-kadang, kita ingin membatasi satu parameter jenis berdasarkan yang lain. Itu seperti mengatakan, "Kotak ini hanya dapat menampung item yang kompatibel dengan apa yang sudah ada di dalamnya."
Marilah kita lihat contoh:
function copyProperties<T extends U, U>(target: T, source: U): T {
for (let id in source) {
target[id] = source[id];
}
return target;
}
Apa yang sedang terjadi di sini?
- Kita memiliki dua parameter jenis:
T
danU
. -
T extends U
berartiT
harus setidaknya semua yangU
punya, tetapi bisa saja memiliki lebih. - Hal ini memungkinkan kita untuk menyalin properti dari
source
ketarget
, dengan mengetahui bahwatarget
akan memiliki semua properti yangsource
punya.
Marilah kita lihat dalam praktik:
interface Person {
name: string;
}
interface Employee extends Person {
employeeId: number;
}
let person: Person = { name: "Alice" };
let employee: Employee = { name: "Bob", employeeId: 123 };
copyProperties(employee, person); // Bekerja!
copyProperties(person, employee); // Kesalahan! Person tidak memiliki employeeId
Practical Applications and Best Practices
Sekarang kita mengerti bagaimana generic constraints bekerja, marilah kita lihat beberapa aplikasi dunia nyata dan praktek terbaik:
- Constraint to Object Types: Seringkali, Anda ingin memastikan Anda bekerja dengan objek:
function cloneObject<T extends object>(obj: T): T {
return { ...obj };
}
- Constraint to Function Types: Anda dapat memastikan jenis adalah callable:
function invokeFunction<T extends Function>(func: T): void {
func();
}
- Constraint to Specific Properties: Memastikan objek memiliki properti tertentu:
function getFullName<T extends { firstName: string; lastName: string }>(obj: T): string {
return `${obj.firstName} ${obj.lastName}`;
}
-
Multiple Constraints: Anda dapat menerapkan beberapa batasan menggunakan operator
&
:
function processData<T extends number & { toFixed: Function }>(data: T): string {
return data.toFixed(2);
}
Berikut adalah tabel yang menggabungkan metode ini:
Method | Description | Example |
---|---|---|
Object Constraint | Memastikan jenis adalah objek | <T extends object> |
Function Constraint | Memastikan jenis adalah callable | <T extends Function> |
Property Constraint | Memastikan jenis memiliki properti tertentu | <T extends { prop: Type }> |
Multiple Constraints | Menggabungkan beberapa batasan | <T extends TypeA & TypeB> |
Conclusion: Embracing the Power of Constraints
Selamat! Anda telah membuka kunci sebuah alat yang kuat di dalam kotak alat TypeScript Anda. Generic constraints memungkinkan kita untuk menulis kode yang fleksibel namun tetap aman, memberikan kita kebaikan terbaik dari kedua dunia.
Ingat, kunci untuk menguasai generic constraints adalah latihan. Cobalah untuk merefactor beberapa kode Anda yang ada untuk menggunakan generik dan constraints. Anda akan terkejut melihat betapa bersih dan kuat kode Anda menjadi!
Sementara kita menutup, ini adalah sedikit humor pemrograman untuk Anda: Mengapa pengembang TypeScript bangkrut? Karena dia menggunakan terlalu banyak batasan generik dan tidak bisa menerima jenis pembayaran apa saja! ?
Teruslah mengoding, terus belajar, dan terutama, bersenang-senang dengan TypeScript!
Credits: Image by storyset