Pelajaran modul (2/2)
Serikat Pekerja dan Penyempitan
Di dunia nyata, variabel dan respons API tidak selalu memiliki satu tipe tetap. TypeScript menawarkan Union Types untuk menangani variabilitas, dan Type Narrowing untuk mengoperasikannya dengan aman saat runtime.
Jenis Serikat
Tipe gabungan memungkinkan variabel menerima nilai dari tipe berbeda. Hal ini dinyatakan dengan menggunakan simbol batang vertikal (|):
let result: number | string;
result = 42; // Valid
result = 'Error 404'; // ValidNamun, saat bekerja dengan tipe gabungan, kita tidak bisa langsung memanggil metode yang hanya dimiliki salah satu tipe tersebut (misalnya, kita tidak bisa memanggil .toUpperCase() jika variabelnya juga bisa berupa number). Pertama-tama kita harus "mempersempit" jenisnya.
Ketik Penyempitan
Penyempitan Tipe adalah proses saat TypeScript menganalisis struktur aliran kontrol (seperti if atau switch) untuk menyimpulkan tipe yang lebih spesifik untuk suatu variabel pada waktu proses.
Ada beberapa cara untuk melakukan penyempitan:
1. Operator typeof
Ideal untuk membedakan tipe primitif:
function printLength(value: string | number) {
if (typeof value === 'string') {
// TypeScript knows 'value' is a string here
console.log(value.length);
} else {
// TypeScript knows 'value' is a number here
console.log(value.toFixed(2));
}
}2. Operator in
Digunakan untuk memeriksa apakah ada properti tertentu pada suatu objek:
interface Fish {
swim: () => void;
}
interface Bird {
fly: () => void;
}
function move(animal: Fish | Bird) {
if ('swim' in animal) {
animal.swim(); // Narrowing to Fish
} else {
animal.fly(); // Narrowing to Bird
}
}Serikat Pekerja yang Didiskriminasi
Pola Serikat Terdiskriminasi terdiri dari pembuatan objek yang berbagi properti umum dengan nilai literal yang unik (disebut diskriminator). TypeScript mengenali diskriminator ini dan secara otomatis mempersempit tipe dalam blok bersyarat.
interface SuccessResponse {
status: 'success'; // Literal discriminator
data: string;
}
interface ErrorResponse {
status: 'error'; // Literal discriminator
errorMessage: string;
}
type ApiResponse = SuccessResponse | ErrorResponse;
function handleResponse(response: ApiResponse) {
if (response.status === 'success') {
console.log('Data received:', response.data);
} else {
console.error('An error occurred:', response.errorMessage);
}
}Cobalah sendiri
Latihan 1: Jenis Serikat
Deklarasikan variabel bernama id yang dapat berupa angka atau string. Inisialisasi terlebih dahulu dengan angka 101, lalu tetapkan nilai string 'USER-101'.
Tunjukkan petunjuk
Gunakan | operator untuk menggabungkan nomor dan string dalam deklarasi variabel let.
Solusi tersedia setelah 3 upaya
Latihan 2: Penyempitan Tipe Dasar
Buat fungsi bernama formatInput yang menerima input parameter bertipe string atau angka. Jika input berupa string, kembalikan input yang dikonversi menjadi huruf besar. Jika berupa angka, kembalikan input dikalikan 2. Tentukan tipe secara eksplisit.
Tunjukkan petunjuk
Gunakan typeof input === 'string' di dalam blok if untuk mencabangkan perilaku.
Solusi tersedia setelah 3 upaya
Latihan 3: Mempersempit dengan 'dalam'
Mengingat dua antarmuka Mobil (dengan metode berkendara) dan Perahu (dengan metode berlayar), tuliskan sebuah fungsi bernama moveVehicle yang menerima parameter kendaraan bertipe Mobil atau Perahu. Jika kendaraan memiliki properti drive, jalankan metode drive(). Jika tidak, jalankan metode Sail().
Tunjukkan petunjuk
Gunakan operator dalam bentuk 'drive' di kendaraan untuk mempersempit antarmuka.
Solusi tersedia setelah 3 upaya
Latihan 4: Bentuk Persatuan yang Didiskriminasi
Tentukan tipe Bentuk yang merupakan gabungan dari dua tipe: Lingkaran dan Kotak. Lingkaran memiliki properti jenis yang disetel ke 'lingkaran' (nilai literal) dan radius (angka). Persegi memiliki properti jenis yang disetel ke 'persegi' (nilai literal) dan sisi (angka). Kemudian tulis fungsi getArea yang menerima bentuk bertipe Shape dan mengembalikan luas sebagai angka (untuk lingkaran Math.PI * radius * radius, untuk sisi persegi * sisi).
Tunjukkan petunjuk
Gunakan shape.kind === 'circle' di dalam getArea untuk membedakan jenis dan menghitung luas yang benar.
Solusi tersedia setelah 3 upaya