Как удалить элемент из массива в TypeScript? Подробное руководство
Основные способы удаления элементов из массива в TypeScript
В TypeScript, как и в JavaScript, есть несколько способов удаления элементов из массива. Выбор метода зависит от того, хотите ли вы изменить исходный массив (мутировать его) или создать новый массив без удалённого элемента. Рассмотрим оба подхода.
1. Немутирующий подход: метод filter()
Это рекомендуемый способ в TypeScript, особенно если вы работаете с иммутабельными данными (например, в React или Redux). Метод filter() создаёт новый массив, не изменяя исходный:
interface Task {
id: number;
title: string;
completed: boolean;
}
const tasks: Task[] = [
{ id: 1, title: 'Купить молоко', completed: false },
{ id: 2, title: 'Сделать домашку', completed: true },
{ id: 3, title: 'Позвонить другу', completed: false }
];
// Удаляем задачу с id = 2
const updatedTasks: Task[] = tasks.filter(task => task.id !== 2);
console.log(updatedTasks);
// [{ id: 1, title: 'Купить молоко', completed: false },
// { id: 3, title: 'Позвонить другу', completed: false }]
console.log(tasks.length); // 3 - исходный массив не изменился
2. Мутирующий подход: метод splice()
Если вам нужно изменить исходный массив, используйте splice(). Но помните: для этого переменная должна быть объявлена через let, а не const:
let tasks: Task[] = [
{ id: 1, title: 'Купить молоко', completed: false },
{ id: 2, title: 'Сделать домашку', completed: true },
{ id: 3, title: 'Позвонить другу', completed: false }
];
// Находим индекс элемента для удаления
const indexToRemove = tasks.findIndex(task => task.id === 2);
if (indexToRemove !== -1) {
tasks.splice(indexToRemove, 1);
}
console.log(tasks.length); // 2 - исходный массив изменился
3. Удаление по значению (для примитивов)
Если у вас массив примитивов (строки, числа), можно использовать indexOf() + splice():
let numbers: number[] = [10, 20, 30, 40];
const index = numbers.indexOf(20);
if (index !== -1) {
numbers.splice(index, 1);
}
// numbers: [10, 30, 40]
4. Удаление последнего элемента: pop()
Метод pop() удаляет последний элемент и возвращает его:
const lastTask: Task | undefined = tasks.pop();
if (lastTask) {
console.log(`Удалена задача: ${lastTask.title}`);
}
5. Удаление первого элемента: shift()
Метод shift() удаляет первый элемент и возвращает его:
const firstTask: Task | undefined = tasks.shift();
Важные моменты для TypeScript
- Тип возвращаемого значения:
filter()возвращает массив того же типа, что и исходный.pop()иshift()возвращаютT | undefined, поэтому используйте проверку наundefined. - ReadonlyArray: если ваш массив объявлен как
readonly, используйте толькоfilter():
const readonlyTasks: readonly Task[] = [/* ... */];
// readonlyTasks.splice(...) // Ошибка! Мутация запрещена
const filtered = readonlyTasks.filter(t => t.id !== 2); // Работает
Какой метод выбрать?
- filter() — для иммутабельного подхода (рекомендуется).
- splice() — если нужно изменить исходный массив (используйте
let). - pop() / shift() — для удаления первого/последнего элемента.
В вашем случае с задачами лучше всего подойдёт filter(), так как он не мутирует исходные данные и хорошо сочетается с TypeScript типами.
Альтернативный подход: утилитарная функция для удаления
Если вам часто приходится удалять элементы из массивов, можно создать вспомогательную функцию, которая будет работать с любым типом данных:
function removeItem<T>(arr: T[], predicate: (item: T) => boolean): T[] {
return arr.filter(item => !predicate(item));
}
// Использование
const tasks: Task[] = [/* ... */];
const tasksWithoutId2 = removeItem(tasks, task => task.id === 2);
// Или удаление по индексу
function removeAtIndex<T>(arr: T[], index: number): T[] {
return [...arr.slice(0, index), ...arr.slice(index + 1)];
}
const tasksWithoutIndex1 = removeAtIndex(tasks, 1);
Использование delete (не рекомендуется)
Оператор delete не удаляет элемент из массива, а лишь устанавливает значение undefined на указанном индексе. Длина массива не меняется:
const arr = [1, 2, 3];
delete arr[1]; // arr становится [1, undefined, 3]
console.log(arr.length); // 3
Избегайте использования delete для массивов — это приводит к "дырам" в массиве и может вызвать неожиданное поведение.
Для продвинутых: работа с Set
Если порядок элементов не важен и у вас уникальные значения, можно использовать Set:
const taskIds = new Set(tasks.map(t => t.id));
taskIds.delete(2);
const filteredTasks = tasks.filter(t => taskIds.has(t.id));
Этот подход может быть эффективнее при больших объёмах данных, так как Set.has() работает за O(1).