За счёт статической типизации и дополнительных синтаксических возможностей TypeScript существенно расширяет работу с массивами по сравнению с JavaScript.
Подробнее о массивах JavaScript читайте в нашем самоучителе JavaScript в главе о массивах.
Базовые способы объявления массива
В TypeScript есть два равноправных синтаксиса для указания типа массива:
- Квадратные скобки (более распространённый):
Пример
let numbers: number[] = [1, 2, 3]; let names: string[] = ["Alice", "Bob"]; - Обобщённый тип
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");
}