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-ийн дотор төрлийг "задлан авах" хамгийн хүчирхэг аргыг сурна.