Типи шаблонних літералів у TypeScript
Що таке типи шаблонних літералів?
Типи шаблонних літералів базуються на типах літералів рядків, використовуючи синтаксис шаблонних літералів (\...``) для створення нових типів літералів рядків через конкатенацію рядків на рівні типів.
Основний синтаксис
typescript
type Greeting = `Hello, ${string}`;
const a: Greeting = "Hello, World"; // ✅
const b: Greeting = "Hello, Alice"; // ✅
const c: Greeting = "Hi, World"; // ❌ ПомилкаПоєднання літеральних об'єднань
typescript
type Color = "red" | "blue" | "green";
type Size = "small" | "large";
type ColorSize = `${Size}-${Color}`;
// "small-red" | "small-blue" | "small-green" | "large-red" | "large-blue" | "large-green"TypeScript генерує всі можливі комбінації — це називається дистрибутивним типом шаблонних літералів.
Вбудовані типи маніпуляції рядками
typescript
type Upper = Uppercase<"hello">; // "HELLO"
type Lower = Lowercase<"HELLO">; // "hello"
type Cap = Capitalize<"hello">; // "Hello"
type Uncap = Uncapitalize<"Hello">; // "hello"
// У поєднанні з шаблонними літералами
type EventName = "click" | "focus" | "blur";
type HandlerName = `on${Capitalize<EventName>}`;
// "onClick" | "onFocus" | "onBlur"Практичні випадки використання
CSS утилітарні класи
typescript
type Spacing = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 8;
type Direction = "t" | "b" | "l" | "r" | "x" | "y";
type PaddingClass = `p${Direction}-${Spacing}`;
// "pt-0" | "pt-1" | ... | "py-8"
type MarginClass = `m${Direction}-${Spacing}`;Безпечний за типом еміттер подій
typescript
type Events = {
userCreated: { id: string; name: string };
userDeleted: { id: string };
orderPlaced: { orderId: string; total: number };
};
type EventHandler<T extends keyof Events> = (data: Events[T]) => void;
type OnMethod = `on${Capitalize<string & keyof Events>}`;
// "onUserCreated" | "onUserDeleted" | "onOrderPlaced"Типи маршрутів API
typescript
type ApiVersion = "v1" | "v2";
type Resource = "users" | "posts" | "comments";
type ApiRoute = `/api/${ApiVersion}/${Resource}`;
// "/api/v1/users" | "/api/v1/posts" | ... | "/api/v2/comments"
type IdRoute = `${ApiRoute}/${string}`;
// "/api/v1/users/..." тощо.Шаблони ключів об'єкта
typescript
type GetterName<T extends string> = `get${Capitalize<T>}`;
type SetterName<T extends string> = `set${Capitalize<T>}`;
type Getters<T> = {
[K in keyof T as GetterName<string & K>]: () => T[K];
};
type Setters<T> = {
[K in keyof T as SetterName<string & K>]: (value: T[K]) => void;
};
interface Person { name: string; age: number; }
type PersonGetters = Getters<Person>;
// { getName: () => string; getAge: () => number }
type PersonSetters = Setters<Person>;
// { setName: (value: string) => void; setAge: (value: number) => void }Виведення в межах шаблонних літералів
typescript
type ExtractRouteParams<T extends string> =
T extends `${string}:${infer Param}/${infer Rest}`
? Param | ExtractRouteParams<Rest>
: T extends `${string}:${infer Param}`
? Param
: never;
type Params = ExtractRouteParams<"/users/:userId/posts/:postId">;
// "userId" | "postId"Важливо:
Типи шаблонних літералів є потужною функцією для створення безпечних за типом рядкових шаблонів. Вони широко використовуються для імен подій, CSS класів, маршрутів API та переназначення ключів у відображених типах. У поєднанні з Capitalize, Uppercase тощо, вони дозволяють виразну маніпуляцію рядками на рівні типів.
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.