Mapped Types
Partial, Required, Pick, Omit зэрэг utility types-ийн "дотор" яг юу болж байдагыг мэдэх үү? Тэдгээр бүгд mapped type дээр суурилдаг. Mapped type нь байгаа төрлийн бүх property-г тойрч гарч, тус бүрт хувиргалт хийх зориулалттай.
Mapped type-ийн синтакс
// Үндсэн синтакс
type Хувиргасан<T> = {
[K in keyof T]: T[K];
};
K— property-ийн нэр (түлхүүр)keyof T— T-ийн бүх property нэрүүдийн unionT[K]— тухайн property-ийн төрөл
Энэ нь for...in давталттай маш төстэй боловч төрлийн систем дотор ажиллана:
interface Хэрэглэгч {
нэр: string;
нас: number;
идэвхтэй: boolean;
}
// Бүх property-г string болгох хувиргалт
type БүгдМөр<T> = {
[K in keyof T]: string;
};
type МөрХэрэглэгч = БүгдМөр<Хэрэглэгч>;
// { нэр: string; нас: string; идэвхтэй: string }
? ба readonly нэмэх/хасах
Mapped type-д ? ба readonly-г нэмж эсвэл хасаж болно:
interface Бүтээгдэхүүн {
нэр: string;
үнэ: number;
тайлбар: string;
}
// Бүх property optional болгох — Partial-ийн хэрэгжилт яг ингэж ажилладаг
type МөрөнPartial<T> = {
[K in keyof T]?: T[K];
};
// Бүх property readonly болгох
type БүгдReadonly<T> = {
readonly [K in keyof T]: T[K];
};
// ? хасах — Required-ийн хэрэгжилт
type МөрөнRequired<T> = {
[K in keyof T]-?: T[K];
};
// readonly хасах
type МутабельТөрөл<T> = {
-readonly [K in keyof T]: T[K];
};
-? гэдэг нь "optional тэмдгийг хас" гэсэн утгатай. TypeScript-ийн суурилсан Required<T> яг энэ аргаар бичигдсэн.
Төрлийг хувиргах mapped type
Property-ийн утгын төрлийг өөрчилж болно:
// Бүх утгыг Promise болгох
type Амлалт<T> = {
[K in keyof T]: Promise<T[K]>;
};
// Бүх утгыг функц болгох
type Геттер<T> = {
[K in keyof T]: () => T[K];
};
interface Тохиргоо {
хост: string;
порт: number;
отладка: boolean;
}
type ТохиргооГеттер = Геттер<Тохиргоо>;
// {
// хост: () => string;
// порт: () => number;
// отладка: () => boolean;
// }
as — property нэрийг хувиргах
TypeScript 4.1-с эхлэн as ашиглан property нэрийг мөн өөрчилж болно:
// Бүх property-д "авах_" угтвар нэмэх
type УгтвартайГеттер<T> = {
[K in keyof T as `авах_${string & K}`]: () => T[K];
};
interface Хэрэглэгч {
нэр: string;
нас: number;
}
type ХэрэглэгчГеттер = УгтвартайГеттер<Хэрэглэгч>;
// {
// авах_нэр: () => string;
// авах_нас: () => number;
// }
Бодит жишээ: form validation объект
interface БүртгэлийнФорм {
нэр: string;
имэйл: string;
нууц_үг: string;
нас: number;
}
// Тус бүр талбарт алдааны мессеж хадгалах
type АлдааныТөлөв<T> = {
[K in keyof T]: string | null;
};
type БүртгэлийнАлдаа = АлдааныТөлөв<БүртгэлийнФорм>;
// {
// нэр: string | null;
// имэйл: string | null;
// нууц_үг: string | null;
// нас: string | null;
// }
const алдаанууд: БүртгэлийнАлдаа = {
нэр: null,
имэйл: "Имэйл буруу форматтай байна",
нууц_үг: "Нууц үг хэт богино байна",
нас: null,
};
Mapped type нь нэг удаа тодорхойлоод, дурын interface-д хэрэглэж болох хэрэглүүр болдог. Form validation, API хариу зохицуулалт, өгөгдлийн хувиргалт зэрэг олон газар ашиглагддаг TypeScript-ийн хамгийн хүчирхэг онцлогуудын нэг.
Дараагийн хичээлд:
Conditional Types — T extends U ? X : Y синтакс ашиглан нөхцлөөс хамааран өөр өөр төрөл буцаадаг нарийн хэрэглүүрийг сурна.