TypeScript Массивы

За счёт статической типизации и дополнительных синтаксических возможностей TypeScript существенно расширяет работу с массивами по сравнению с JavaScript.

Подробнее о массивах JavaScript читайте в нашем самоучителе JavaScript в главе о массивах.


Базовые способы объявления массива

В TypeScript есть два равноправных синтаксиса для указания типа массива:

  1. Квадратные скобки (более распространённый):

    Пример

    
    let numbers: number[] = [1, 2, 3];
    let names: string[] = ["Alice", "Bob"];
    
    
  2. Обобщённый тип Array<T>:

    Пример

    
    let numbers: Array<number> = [1, 2, 3];
    let names: Array<string> = ["Alice", "Bob"];
    
    

Важно: оба варианта семантически идентичны. Выбор — вопрос стиля кода.


Типизация элементов

TypeScript требует, чтобы все элементы массива имели одинаковый тип (если не использовать объединения).

Примеры допустимых объявлений:

  • boolean[] — массив булевых значений;
  • string[] — массив строк;
  • any[] — массив любых значений (снижает типовую безопасность);
  • null[] — массив значений null (редко, но возможно).

Пример


let mixed: (string | number)[] = ["hello", 42, "world"]; // допустимо


Инициализация и изменение

  • Инициализация возможна сразу при объявлении:

    
    let fruits: string[] = ["apple", "banana"];
    
    
  • Изменение элементов разрешено:

    
    fruits[0] = "orange"; // OK
    
    
  • Добавление элементов через методы push, unshift и др.:

    
    fruits.push("grape"); // OK
    
    

Массивы только для чтения (readonly)

При помощи модификатора readonly массив можно сделать неизменяемым:

Пример


let readonlyNumbers: readonly number[] = [1, 2, 3];
// или
let readonlyNumbers: ReadonlyArray<number> = [1, 2, 3];

У такого массива

Запрещено:

  • изменение элементов по индексу (readonlyNumbers[0] = 5 — ошибка);
  • вызовы мутирующих методов (push, pop, splice и т. д.).

но

Разрешено:

  • чтение элементов;
  • немутативные методы (map, filter, forEach).

Методы массивов и типизация

TypeScript автоматически выводит типы, если массив изначально содержит значения и для стандартных методов:

  • map: возвращает новый массив с преобразованными элементами;
  • filter: возвращает подмножество элементов по условию;
  • reduce: сводит массив к одному значению;
  • find: ищет первый элемент по условию;
  • includes: проверяет наличие элемента.

Пример с map


let numbers: number[] = [1, 2, 3]; // автоматически определен как тип number[]
let doubled: number[] = numbers.map(n => n * 2); // тип выведен как number[]
numbers.push(4); // без ошибки
numbers.push("2"); // Ошибка: Аргумент типа 'string' не может быть назначен параметру типа 'number'.
let head: number = numbers[0]; // без ошибки


Многомерные массивы

Для массивов массивов указывают вложенные типы:

Пример


let matrix: number[][] = [
  [1, 2, 3],
  [4, 5, 6]
];

let cubes: number[][][] = [
  [[1, 2], [3, 4]],
  [[5, 6], [7, 8]]
];


Опциональные элементы и неопределённая длина

Если длина массива неизвестна, тип просто указывает на элементы:

Пример


let dynamicArray: string[] = []; // может расти
dynamicArray.push("new item"); // OK

Для опциональных элементов используют ?:

Пример


let optionalTuple: [string, number?] = ["hello"]; // второй элемент необязателен


Проверка типов и защита

Оператор Array.isArray — надёжный способ проверить, является ли значение массивом:

Пример


if (Array.isArray(myVar)) {
  // работаем с myVar как с массивом
}

Проверка типов — позволяет сужать тип в условиях:

Пример


function isStringArray(arr: any): arr is string[] {
  return Array.isArray(arr) && arr.every(item => typeof item === "string");
}