TypeScript - Template Literal Types

Здравствуйте, будущие супергерои кодирования! Сегодня мы отправимся в увлекательное путешествие в мир TypeScript и исследуем fascинирующую функцию под названием Template Literal Types. Не волнуйтесь, если вы новички в программировании - я буду вести вас шаг за шагом, как я делал это для countless студентов за годы teaching. Так что возьмите любимый напиток, устроитесь поудобнее и погружайтесь с нами!

TypeScript - Template Literal Types

Что такое Template Literal Types?

Прежде чем мы углубимся в детали, давайте поймем, что такое Template Literal Types. Представьте, что вы создаете поздравительную открытку. У вас есть базовый шаблон, но вы хотите персонализировать его, используя разные имена и сообщения. Вот что делают Template Literal Types в TypeScript - они позволяют нам создавать гибкие, повторно используемые определения типов, которые могут изменяться в зависимости от того, что мы вводим.

Синтаксис

Синтаксис для Template Literal Types может показаться странным сначала, но я обещаю, что это не так сложно, как parece. Вот базовая структура:

type TemplateLiteralType = `prefix ${SomeType} suffix`;

Давайте разберем это:

  • type - это ключевое слово в TypeScript, которое мы используем для определения нового типа.
  • TemplateLiteralType - это имя, которое мы даем нашему новому типу (вы можете выбрать любое имя, которое вам нравится).
  • Обратные кавычки (`) используются для заключения нашего шаблона.
  • ${SomeType} - это метка, где мы можем вставить другой тип.
  • prefix и suffix - это可选 текст, который всегда будет частью нашего типа.

Представьте это как игру Mad Libs, где ${SomeType} - это пробел, который мы заполняем, чтобы создать разные варианты.

Примеры

Теперь давайте рассмотрим несколько примеров, чтобы увидеть, как работают Template Literal Types на практике. Я предоставлю plenty примеров кода и тщательно объясню каждый из них.

Пример 1: Основное использование

type Greeting = `Hello, ${string}!`;

let myGreeting: Greeting = "Hello, World!";  // Это правильно
let invalidGreeting: Greeting = "Hi there!"; // Это вызовет ошибку

В этом примере мы создали тип Greeting, который всегда должен начинаться с "Hello, " и заканчиваться "!". Часть ${string} означает, что мы можем inserting любой строку между ними. Это как если бы у вас был шаблон для открытки, где вы можете только изменить имя.

Пример 2: Combining String Literals

type Color = "red" | "blue" | "green";
type Size = "small" | "medium" | "large";

type TShirt = `${Size}-${Color}`;

let myShirt: TShirt = "medium-blue";  // Это правильно
let invalidShirt: TShirt = "tiny-yellow";  // Это вызовет ошибку

Здесь мы создаем тип TShirt, комбинируя два других типа: Size и Color. Это позволяет нам создавать допустимые комбинации, такие как "small-red" или "large-green", но предотвращает недопустимые, такие как "tiny-yellow".

Пример 3: Использование чисел

type Coordinate = `${number},${number}`;

let point: Coordinate = "10,20";  // Это правильно
let invalidPoint: Coordinate = "10,20,30";  // Это вызовет ошибку

В этом примере мы используем number вместо string. Это создает тип, который представляет 2D координату. Он должен состоять из двух чисел, разделенных запятой.

Пример 4: Complex Templates

type HttpMethod = "GET" | "POST" | "PUT" | "DELETE";
type ApiEndpoint = `/${string}`;

type ApiRoute = `${HttpMethod} ${ApiEndpoint}`;

let validRoute: ApiRoute = "GET /users";
let anotherValidRoute: ApiRoute = "POST /update-profile";
let invalidRoute: ApiRoute = "PATCH /items";  // Это вызовет ошибку

Этот пример показывает, как мы можем создавать более сложные типы. Мы определяем тип ApiRoute, который combines HTTP-метод с конечной точкой. Это обеспечивает, чтобы наши API-маршруты всегда следовали определенному формату.

Пример 5: Uppercase и Lowercase Modifiers

type Greeting = "hello" | "hi" | "hey";
type ShoutingGreeting = Uppercase<Greeting>;
type WhisperingGreeting = Lowercase<Greeting>;

let loud: ShoutingGreeting = "HELLO";  // Это правильно
let soft: WhisperingGreeting = "hi";   // Это правильно
let invalid: ShoutingGreeting = "Hey"; // Это вызовет ошибку

TypeScript также предоставляет утилиты типов, такие как Uppercase и Lowercase, которые мы можем использовать с нашими Template Literal Types. Этот пример показывает, как мы можем создавать новые типы, которые являются версиями в верхнем или нижнем регистре существующих типов.

Methods Table

Вот таблица, резюмирующая ключевые методы и утилиты, которые мы обсуждали:

Method/Utility Description Example
Basic Template Создает тип с固定的 prefix/suffix и переменной частью type Greeting = 'Hello, ${string}!'
Union Types Combines multiple string literal types type Color = "red" \| "blue" \| "green"
Uppercase Преобразует строковый literal type в верхний регистр type Upper = Uppercase<"hello">
Lowercase Преобразует строковый literal type в нижний регистр type Lower = Lowercase<"HELLO">

Заключение

И вот оно, мои дорогие студенты! Мы исследовали удивительный мир Template Literal Types в TypeScript. От базового использования до более сложных примеров, вы видели, как эта функция может помочь нам создавать более точные и гибкие определения типов.

Помните, как и при обучении любому новому навыку, овладение Template Literal Types требует практики. Не отчаивайтесь, если это не сработает сразу - я видел countless студентов, которые сначала мучались, а потом hatten того "ура!" момент. Продолжайте экспериментировать, try создавать свои собственные типы, и, самое главное, получайте удовольствие от этого!

За годы teaching я обнаружил, что студенты, которые наслаждаются процессом обучения, те, кто excel. Так что думайте о TypeScript как о мощном инструменте в вашем наборе для программирования, и Template Literal Types как о швейцарском армейском ноже внутри этого набора - универсальном, точном и incredibly полезном, когда вы знаете, как им пользоваться.

Теперь идите вперед и создавайте удивительные вещи с вашими новыми знаниями. И помните, в мире программирования единственное ограничение - это ваша фантазия (и, возможно, иногда ваш компилятор, но это уже другая история). Счастливого кодирования!

Credits: Image by storyset