Если вы когда-либо использовали TypeScript, вы должны знать хотя бы такие примитивные типы, как строка, число и логическое значение. Несмотря на то, что большую часть времени вы используете их напрямую или в качестве типов свойств интерфейса, вряд ли какое-либо приложение сможет избежать использования более продвинутых методов.

Каждый из этих типов имеет подробную документацию, доступную на официальном сайте и других онлайн-ресурсах. Я не хочу вас обманывать — большинство из них довольно хороши, но поиск в Google и статьях того, что мне нужно, всегда вызывает когнитивную перегрузку, которой мне хотелось бы избежать.

Я планирую добавить эту статью в закладки, как только она будет завершена, и использовать ее для дальнейшего использования, если я забуду (снова), как работают эти типы.

Общие типы

Документация: Дженерики

Обычно внутри функции мы уже знаем, какой тип она должна возвращать.

function sum(a: number, b: number): number {
  return a + b
}

Однако все может быть иначе. Возможно, функция возвращает значения разных типов в зависимости от переданных аргументов. Рассмотрим таблицу с конфигурациями для внешних вызовов API, содержащую записи с двумя полями — slug и value.

Теперь, если вы хотите иметь функцию, которая извлекает значение конфигурации по пулу, она будет возвращать разные типы в зависимости от переданного пула. Вот тут-то и пригодится универсальный тип. Под универсальным типом можно понимать тип, передаваемый в качестве аргумента функции. Давайте продемонстрируем это:

function main(): void {
  const throttleLimit = getConfig<number>('throttle-limit')
  const apiEndpoint = getConfig<string>('api-endpoint')
  
}
function getConfig<T>(slug: string): T {
  return getValue(slug) // do whatever is needed to get the value from db
}

Синтаксис может быть не очень интуитивным, но он все равно прост. Когда вы вызываете функцию, которая ожидает универсальный тип, вы передаете ее в угловых скобках между именем функции и аргументами, например:

getConfig‹number('ограничение скорости')

А затем оно снова фиксируется в функции между именем и аргументами:

getConfig‹T›(слаг: строка).

Называть его «T» – это просто общепринятое соглашение; вы можете использовать любое другое имя. В конце концов его можно будет использовать так же, как и любые другие типы внутри функции.

Типы союзов

Документация: Союзы

Это представляет собой очень простую концепцию. С точки зрения синтаксиса это просто вертикальная черта “|” символ, который можно прочитать как логический оператор ИЛИ (||). Мы можем использовать предыдущий пример и переписать его следующим образом:

function main(): void {
  const throttleLimit = getConfig('throttle-limit')
  const apiEndpoint = getConfig('api-endpoint')
  
}
function getConfig(slug: string): string | number {
  return getValue(slug) // do whatever is needed to get the value from db
}

Конечно, это не идеальное решение для производства, поскольку значения могут быть разных типов.

Типы пересечений

Документация: Типы пересечений

Если типы объединения аналогичны логическому оператору ИЛИ, то типы пересечения аналогичны логическому оператору И. Распространенный случай использования возникает, когда у вас есть стандартный интерфейс, описывающий объект, но в конкретном сценарии вам необходимо расширить его новыми полями.

function supplyWithCallsLeft(apiResponse): Response & {callsLeft: number} => {
  return {
    ...Response, 
    callsLeft: Response.ApiCallsLimit - Response.ApiCallsCount
  }
}

Очевидно, что Ответ не должен содержать вычисленные значения, подобные этому; следовательно, и соответствующий интерфейс. Но если вам нужно что-то подобное, вам пригодятся типы пересечений.

Сопоставленные типы

Документация: Сопоставленные типы

Для тех, кто относительно плохо знаком с TypeScript, отображаемые типы могут оказаться весьма привлекательными.

Представьте себе типичную ситуацию: у вас есть старомодный объект «ключ-значение», и вы не знаете, какие именно ключи будут использоваться, но знаете их типы.

type Mapping = {
  [key: string]: string
}

Этот тип будет охватывать следующий пример:

const animalsToSizeMapping: Mapping = {
  'dog'  : 'big',
  'cat'  : 'small,
  'mouse': 'tiny'
}

Не ожидайте, что ваше отображение будет настолько хорошим, но, скорее всего, есть вещи, которые вы захотите отобразить в своем приложении.

Типы строковых литералов

Документация: Литеральные типы

Вероятно, самый простой, но из-за его очень специфического поведения в некоторых случаях он может быть очень полезен. Идея проста: в то время как тип string проверяет, является ли значение какой-либо строкой, тип строковый литерал проверяет, является ли значение точной строкой. . Давайте последуем предыдущему примеру и определим тип животных:

type Animal = 'dog' | 'cat' | 'mouse'

Эта функция будет работать нормально:

function speak(animal: Animal) {
  if(animal === 'dog') {
    console.log('woof-woof')
  }
  if(animal === 'cat') {
    console.log('meow-meow')
  }
  if(animal === 'mouse') {
    console.log('pi-pi-pi')
  }
}

Но добавление чего-либо из списка приведет к ошибке TypeScript:

function speak(animal: Animal) {
  if(animal === 'dog') {
    console.log('woof-woof')
  }
  if(animal === 'cat') {
    console.log('meow-meow')
  }
  if(animal === 'mouse') {
    console.log('pi-pi-pi')
  }
  if(animal === 'frog') {
    // TypeScript would tell you that 'Animal' and '"frog"' have no overlap
    console.log('croak-croak')
}

Очевидно, это может уберечь вас от ошибок в написании и предоставить некоторую документацию по коду. Это также помогает при моделировании концепций, специфичных для предметной области, с ограниченным набором возможных значений.

Заключение

Изучение новых концепций и освоение TypeScript открывает различные возможности для решения задач, используя на выходе хороший и читаемый код, вместо того, чтобы полагаться на банальные методы.

Я советую вам найти больше полезных функций TypeScript и поделиться ими в разделе комментариев!

Стеккадемический

Спасибо, что дочитали до конца. Прежде чем уйти:

  • Пожалуйста, рассмотрите возможность аплодировать и следовать автору! 👏
  • Следуйте за нами в Twitter(X), LinkedIn и YouTube.
  • Посетите Stackademic.com, чтобы узнать больше о том, как мы демократизируем бесплатное образование в области программирования во всем мире.