TypeScript / Template Literal Types
Template Literal Types
JavaScript-д template literal (\Сайн уу, ${нэр}!``) нь мөрийг динамикаар үүсгэдэг. TypeScript 4.1-с эхлэн энэ синтаксийг төрлийн системд мөн ашиглах боломжтой болсон. Template literal type нь мөрийн literal төрлүүдийг хослуулан шинэ төрөл үүсгэдэг.
Үндсэн синтакс
typescript
// Энгийн мөрийн literal hoslol
type Мэндчилгээ = `Сайн уу, ${string}!`;
const зөв: Мэндчилгээ = "Сайн уу, Болд!"; // ✅
const зөв2: Мэндчилгээ = "Сайн уу, TypeScript!"; // ✅
// const буруу: Мэндчилгээ = "Баяртай!"; // ❌ загварт таарахгүй
// Union-тэй хослуулах — бүх хослолыг автоматаар үүсгэнэ
type Чиг = "зүүн" | "баруун" | "дээш" | "доош";
type ЧигийнМессеж = `${Чиг} тийш явна`;
// TypeScript дараах бүх хослолыг үүсгэнэ:
// "зүүн тийш явна" | "баруун тийш явна" | "дээш тийш явна" | "доош тийш явна"
const мессеж: ЧигийнМессеж = "зүүн тийш явна"; // ✅
// const буруу: ЧигийнМессеж = "хойш тийш явна"; // ❌
Property нэр автоматаар үүсгэх
Template literal type нь mapped type-тэй хослуулах үед маш хүчирхэг болдог:
typescript
interface Хэрэглэгч {
нэр: string;
нас: number;
хот: string;
}
// Тус бүр property-д "өөрчлөгдсөн_" угтвар нэмсэн event нэмнэ
type ӨөрчлөлтийнЭвент<T> = {
[K in keyof T as `өөрчлөгдсөн_${string & K}`]: T[K];
};
type ХэрэглэгчЭвент = ӨөрчлөлтийнЭвент<Хэрэглэгч>;
// {
// өөрчлөгдсөн_нэр: string;
// өөрчлөгдсөн_нас: number;
// өөрчлөгдсөн_хот: string;
// }
Getter ба Setter автоматаар үүсгэх
typescript
interface Тохиргоо {
хост: string;
порт: number;
отладка: boolean;
}
// "авах_" угтвартай getter нэмэр
type ГеттертэйТохиргоо<T> = T & {
[K in keyof T as `авах_${string & K}`]: () => T[K];
} & {
[K in keyof T as `тавих_${string & K}`]: (утга: T[K]) => void;
};
// Үр дүн:
// {
// хост: string; авах_хост: () => string; тавих_хост: (утга: string) => void;
// порт: number; авах_порт: () => number; тавих_порт: (утга: number) => void;
// отладка: boolean; авах_отладка: () => boolean; тавих_отладка: (утга: boolean) => void;
// }
Суурилсан string manipulation types
TypeScript нь мөрийн literal-ыг хувиргах дөрвөн суурилсан utility type-тэй:
typescript
type Жишээ = "сайн уу дэлхий";
type Том = Uppercase<Жишээ>; // "САЙН УУ ДЭЛХИЙ"
type Жижиг = Lowercase<"МОНГОЛ">; // "монгол"
type НэгдүгээрТом = Capitalize<"болд">; // "Болд"
type НэгдүгээрЖижиг = Uncapitalize<"Болд">; // "болд"
// Бодит хэрэглээ — event нэрийг автоматаар үүсгэх
type EventНэр<T extends string> = `on${Capitalize<T>}`;
type ДарсанЭвент = EventНэр<"дарсан">; // "onДарсан"
type АчаалсанЭвент = EventНэр<"ачааллав">; // "onАчааллав"
Бодит жишээ: CSS class нэр үүсгэх
typescript
type Хэмжээ = "жижиг" | "дунд" | "том";
type Өнгө = "анхдагч" | "аюул" | "амжилт";
type Вариант = "дүүргэсэн" | "хүрээтэй" | "тунгалаг";
// Бүх хослолоос CSS class нэр үүсгэнэ
type ButtonClass = `товч-${Хэмжээ}-${Өнгө}-${Вариант}`;
// TypeScript 3 × 3 × 3 = 27 хослол бүгдийг мэднэ
const класс1: ButtonClass = "товч-жижиг-анхдагч-дүүргэсэн"; // ✅
const класс2: ButtonClass = "товч-том-аюул-хүрээтэй"; // ✅
// const буруу: ButtonClass = "товч-аварга-анхдагч-дүүргэсэн"; // ❌
Template literal type нь API endpoint нэр, CSS class, event handler, Redux action — мөрийн тогтсон форматтай дурын зүйлийг алдаагүй бичихэд маш хэрэгтэй. Нэг удаа тодорхойлоод IDE автоматаар зөв хослолуудыг санал болгодог болно.
Дараагийн хичээлд:
infer түлхүүр үг — conditional type-ийн дотор төрлийг "задлан авах" хамгийн хүчирхэг аргыг сурна.