Panduan Pemula untuk Tipe Mapped dalam TypeScript
Hai sana, para ahli TypeScript masa depan! Hari ini, kita akan memulai perjalanan yang menarik ke dalam dunia Tipe Mapped. Jangan khawatir jika Anda baru dalam pemrograman - saya akan menjadi panduan ramah Anda, dan kita akan berjalan langkah demi langkah. Pada akhir panduan ini, Anda akan dapat memetakan tipe seperti seorang pro!
Apa Itu Tipe Mapped?
Sebelum kita mendalam, mari kita memahami apa itu Tipe Mapped. Bayangkan Anda memiliki kotak cokelat campuran, dan Anda ingin membuat kotak baru di mana setiap cokelat diwrapping dengan foil emas. Itu adalah esensi apa yang dilakukan Tipe Mapped dalam TypeScript - mereka mengambil tipe yang sudah ada dan transformasikan menjadi tipe baru berdasarkan set aturan.
Tipe Mapped Bawaan
TypeScript datang dengan beberapa Tipe Mapped yang sudah didefinisikan dan sangat berguna. Mari kita lihat satu per satu:
1. Partial<T>
Tipe Partial<T>
membuat semua properti T
menjadi opsional. Itu seperti mengubah resep ketat menjadi resep fleksibel di mana Anda dapat melewatkan beberapa bahan.
interface Recipe {
name: string;
ingredients: string[];
cookingTime: number;
}
type FlexibleRecipe = Partial<Recipe>;
// Sekarang kita dapat membuat resep tanpa semua properti
const quickSnack: FlexibleRecipe = {
name: "Toast",
// Kita dapat melewatkan ingredients dan cookingTime
};
Dalam contoh ini, FlexibleRecipe
memungkinkan kita membuat resep tanpa menentukan semua properti. Itu sempurna saat Anda ingin memperbarui hanya sebagian objek.
2. Required<T>
Required<T>
adalah kebalikan dari Partial<T>
. Itu membuat semua properti wajib, bahkan jika mereka opsional dalam tipe asli.
interface UserProfile {
name: string;
age?: number;
email?: string;
}
type CompleteUserProfile = Required<UserProfile>;
// Sekarang kita harus menyediakan semua properti
const user: CompleteUserProfile = {
name: "Alice",
age: 30,
email: "[email protected]"
};
Di sini, CompleteUserProfile
memastikan bahwa kita menyediakan semua properti, termasuk age
dan email
yang opsional dalam UserProfile
.
3. Readonly<T>
Readonly<T>
membuat semua properti T
menjadi read-only. Itu seperti memasukkan tipe Anda ke dalam kaca - Anda dapat melihat, tetapi Anda tidak dapat menyentuh!
interface Toy {
name: string;
price: number;
}
type CollectibleToy = Readonly<Toy>;
const actionFigure: CollectibleToy = {
name: "Superhero",
price: 19.99
};
// Ini akan menyebabkan kesalahan
// actionFigure.price = 29.99;
Dalam contoh ini, setelah kita membuat actionFigure
, kita tidak dapat mengubah propertinya. Itu bagus untuk membuat objek tak dapat diubah.
4. Pick<T, K>
Pick<T, K>
membuat tipe baru dengan memilih hanya properti yang ditentukan K
dari T
. Itu seperti memilih fitur favorit Anda dari tipe.
interface Smartphone {
brand: string;
model: string;
year: number;
color: string;
price: number;
}
type BasicPhoneInfo = Pick<Smartphone, 'brand' | 'model'>;
const myPhone: BasicPhoneInfo = {
brand: "TechBrand",
model: "X2000"
};
Di sini, BasicPhoneInfo
hanya termasuk brand
dan model
properti dari Smartphone
, meninggalkan yang lain.
5. Omit<T, K>
Omit<T, K>
adalah kebalikan dari Pick<T, K>
. Itu membuat tipe baru tanpa properti yang ditentukan K
dari T
.
interface Book {
title: string;
author: string;
pages: number;
isbn: string;
}
type BookPreview = Omit<Book, 'pages' | 'isbn'>;
const preview: BookPreview = {
title: "TypeScript Adventures",
author: "Code Wizard"
};
Dalam kasus ini, BookPreview
termasuk semua properti Book
kecuali pages
dan isbn
.
Contoh Penggunaan Tipe Mapped
Sekarang kita telah melihat Tipe Mapped bawaan, mari kita lihat beberapa contoh praktis bagaimana kita dapat menggunakannya dalam konteks dunia nyata.
Contoh 1: Membuat State Form
Bayangkan Anda sedang membuat form, dan Anda ingin mencatat field mana yang telah diubah:
interface LoginForm {
username: string;
password: string;
rememberMe: boolean;
}
type FormTouched = { [K in keyof LoginForm]: boolean };
const touchedFields: FormTouched = {
username: true,
password: false,
rememberMe: true
};
Di sini, kita telah membuat FormTouched
tipe yang memiliki semua kunci seperti LoginForm
, tetapi semua nilai adalah boolean yang menunjukkan apakah field tersebut telah ditentukan.
Contoh 2: Wrapper Respon API
Bayangkan Anda memiliki API yang mengembalikan jenis data yang berbeda, dan Anda ingin membungkus setiap respon dalam format standar:
interface ApiResponse<T> {
data: T;
status: 'success' | 'error';
timestamp: number;
}
type UserData = { id: number; name: string; email: string };
type ProductData = { id: number; name: string; price: number };
const userResponse: ApiResponse<UserData> = {
data: { id: 1, name: "John Doe", email: "[email protected]" },
status: 'success',
timestamp: Date.now()
};
const productResponse: ApiResponse<ProductData> = {
data: { id: 101, name: "Laptop", price: 999.99 },
status: 'success',
timestamp: Date.now()
};
Contoh ini menunjukkan bagaimana kita dapat menggunakan jenis generik dengan Tipe Mapped untuk membuat struktur jenis yang fleksibel dan dapat digunakan kembali.
Membuat Tipe Mapped Khusus
Sekarang, mari kita fungsikan otak TypeScript kita dan buat beberapa Tipe Mapped khusus!
Tipe Khusus 1: Nullable
Buatlah jenis yang membuat semua properti nullable:
type Nullable<T> = { [K in keyof T]: T[K] | null };
interface Person {
name: string;
age: number;
}
type NullablePerson = Nullable<Person>;
const maybePerson: NullablePerson = {
name: "Jane",
age: null // Ini sekarang valid
};
Jenis Nullable<T>
memungkinkan setiap properti untuk menjadi jenis aslinya atau null
.
Tipe Khusus 2: Freezable
Buatlah jenis yang menambahkan metode freeze
ke objek:
type Freezable<T> = T & { freeze(): Readonly<T> };
interface Config {
theme: string;
fontSize: number;
}
function makeFreezable<T>(obj: T): Freezable<T> {
return {
...obj,
freeze() {
return Object.freeze({ ...this }) as Readonly<T>;
}
};
}
const config = makeFreezable<Config>({
theme: "dark",
fontSize: 14
});
const frozenConfig = config.freeze();
// frozenConfig.theme = "light"; // Ini akan menyebabkan kesalahan
Jenis ini menambahkan metode freeze
ke setiap objek, memungkinkan kita untuk membuat versi tak dapat diubah dari itu.
Kesimpulan
Wah, kita telah menempuh jarak yang cukup hari ini! Dari Tipe Mapped bawaan ke membuat jenis khusus sendiri, Anda telah melihat betapa kuat dan fleksibel TypeScript dapat menjadi. Tipe Mapped adalah seperti tongkat sihir dalam peralatan TypeScript Anda - mereka memungkinkan Anda untuk transformasi dan manipulasi jenis dalam cara yang sangat berguna.
Ingat, kunci untuk menguasai Tipe Mapped adalah latihan. Cobalah membuat jenis Anda sendiri, eksperimen dengan kombinasi yang berbeda, dan segera Anda akan menulis kode TypeScript yang tidak hanya fungsional, tetapi elegan dan aman jenisnya.
Tetap mengoding, tetap belajar, dan terutama, bersenang-senang dengan TypeScript!
Credits: Image by storyset