Освоение кортежей TypeScript: подробное руководство

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

Что такое кортежи?

Кортежи — это упорядоченные списки элементов фиксированных типов. В отличие от массивов, где вы можете иметь элементы разных типов, кортежи гарантируют, что каждый элемент принадлежит к определенному типу. Думайте о кортежах как о структурированных контейнерах для связанных данных. Они похожи на «структуры» в C/C++ или «записи» в некоторых других языках.

Вот базовое объявление кортежа в TypeScript:

const coordinates: [number, number] = [10, 20];

В этом примере `координаты` — это кортеж, содержащий два элемента, оба типа `number`.

Объявление и инициализация кортежей

Создать кортежи в TypeScript очень просто. Вы можете объявить и инициализировать их за один шаг:

const person: [string, number] = ["Alice", 30];

Приведенный выше код определяет кортеж `person` с двумя элементами: строкой для имени и числом для возраста.

type NamedTuple = [name: string, age: number, isAdmin: boolean];

const user:NamedTuple=["Alice",33,false];

Мы также можем объявить тип отдельно и присвоить его переменной. Вот пример именованных кортежей, где можно указать имя и тип кортежей.

Массив кортежей

TypeScript поддерживает создание многомерных кортежей с помощью массивов кортежей.

type Coordinates = [number, number][];

const points: Coordinates = [
  [10, 20],
  [30, 40],
  [50, 60],
];

Необязательный элемент в кортежах

Элементы в кортежах также могут быть необязательными. Необязательные элементы указываются с помощью ? в конце типа элемента.

const users: [string, number?][] = [["alice", 2], ["bill"]];

// Adding an extra item throws error
const users: [string, number?] = ["Mike",20,30]; 

Кортежи только для чтения

По умолчанию кортежи изменяемы. Если мы хотим создать неизменяемые кортежи только для чтения, мы можем использовать ключевое слово readonly при определении нашего кортежа.

const readOnlyOfTuples: readonly [string, number] = ["1", 2];
// it throws error becasuse we are trying to modify readonly property
readOnlyOfTuples[1]=2;

Доступ к элементам кортежа

Доступ к элементам внутри кортежа осуществляется с помощью индексации. Доступ к первому элементу осуществляется по индексу «0», ко второму — по индексу «1» и так далее:

const person: [string, number] = ["Alice", 30];
const name = person[0]; // "Alice"
const age = person[1]; // 30

Однако TypeScript предлагает более элегантный способ извлечения элементов с помощью кортежнойдеструктуризации:

const person: [string, number] = ["Alice", 30];
const [name, age] = person;

Это не только упрощает код, но и улучшает читаемость.

Работа с кортежами

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

const coordinates: [number, number] = [10, 20];
// Adding elements
const extendedTuple = […coordinates, 30, 40];
// Removing elements
const [first, …rest] = coordinates;
// Modifying elements
coordinates[0] = 5;

Проверка типов TypeScript гарантирует, что вы случайно не используете кортежи неправильно.

Примеры использования кортежей

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

- Представление координат (широта и долгота).

// Define a tuple for coordinates
type Coordinates = [number, number];

// Example usage:
const myLocation: Coordinates = [37.7749, -122.4194]; // San Francisco coordinates

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

// Define a function that returns a tuple with two values
function getUserInfo(id: string): [string, number] {
  // Simulate fetching user data
  const name = "Alice";
  const age = 30;
  return [name, age];
}

// Example usage:
const [userName, userAge] = getUserInfo("user123");
console.log(`Name: ${userName}, Age: ${userAge}`);

-Кортеж с… оператором распространения

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

function processData(data: [...string[], number]): void {
  console.log(data)
}

processData([12]); // valid
processData(["hello", 123]); // valid
processData(["hello!", "hello!", "hello!", 123]); // valid

processData([1, "hello!", "hello!", 123]); // invalid

Шпаргалка по кортежу:

// Tuple with explicit types & length
const coordinates: [number, number] = [10, 20];

// Array of tuples
const arrOfTuples: [string, number][] = [["1", 2], ["1", 2]];

// Readonly array of tuples
const readOnlyOfTuples: readonly [string, number] = ["1", 2], ["1", 2];

// Tuples with optional items
const optionalItemInTuples: [string, number?][] = [["1", 2], ["1"]];

// Tuple with spread and object
const StringsThenObject: [...string[], { isSuccess: boolean }] = ["string 1", "string 2", { isSuccess: false }];

Заключение

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