> Как проверять конкретный action в reducer в JavaScript/TypeScript? (JavaScript, TypeScript)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: Инрэко

Стек: JavaScript, TypeScript

> Пример ответа

Короткий ответ

В Redux reducer’е конкретный action проверяется через switch-case или if-else по полю action.type. Для TypeScript используют discriminated union: action: Action с общим полем type. Типизация обеспечивает проверку payload на этапе компиляции. В тестах action проверяют через вызов reducer с конкретным action и сравнением возвращённого state с ожидаемым.

Подробное объяснение

Reducer - чистая функция (state, action) => newState. Проверка action’а происходит по его типу. В JavaScript это строка, в TypeScript - литеральный тип из union. Основные подходы:

  • switch-case: классический, читаемый, легко добавлять новые кейсы
  • if-else: гибче для сложной логики, но менее читаем при многих action’ах
  • createReducer из Redux Toolkit: использует builder pattern с addCase, автоматически типизирует action

В TypeScript важно определить тип action как discriminated union:

TYPESCRIPT
type Action =
| { type: 'ADD_TODO'; payload: string }
| { type: 'REMOVE_TODO'; payload: number }
| { type: 'TOGGLE_TODO'; payload: number }

Тогда в каждом case TypeScript сужает тип и знает точную структуру payload.

На практике

В реальных проектах используют Redux Toolkit с createSlice, который генерирует reducer и action creators автоматически. Однако понимание ручной проверки action’ов необходимо для:

  • написания кастомных middleware
  • работы с legacy кодом
  • глубокого понимания Redux
  • отладки сложных кейсов

При тестировании reducer’а проверяют:

  • возврат правильного state для каждого action
  • иммутабельность (не мутируется исходный state)
  • обработку неизвестного action (должен вернуть state как есть)
  • edge cases: пустой payload, граничные значения

Пример кода

TYPESCRIPT
// Определение типов
interface Todo {
id: number;
text: string;
completed: boolean;
}
type Action =
| { type: 'ADD_TODO'; payload: string }
| { type: 'REMOVE_TODO'; payload: number }
| { type: 'TOGGLE_TODO'; payload: number };
// Reducer
function todoReducer(state: Todo[], action: Action): Todo[] {
switch (action.type) {
case 'ADD_TODO':
return [
...state,
{ id: Date.now(), text: action.payload, completed: false }
];
case 'REMOVE_TODO':
return state.filter(todo => todo.id !== action.payload);
case 'TOGGLE_TODO':
return state.map(todo =>
todo.id === action.payload
? { ...todo, completed: !todo.completed }
: todo
);
default:
return state;
}
}
// Тест
describe('todoReducer', () => {
it('should handle ADD_TODO', () => {
const initialState: Todo[] = [];
const newState = todoReducer(initialState, {
type: 'ADD_TODO',
payload: 'Learn Redux'
});
expect(newState).toHaveLength(1);
expect(newState[0].text).toBe('Learn Redux');
expect(newState[0].completed).toBe(false);
});
});

Как отвечать на собеседовании

Начни с базового механизма: switch-case по action.type. Затем покажи понимание TypeScript discriminated unions и как это улучшает type safety. Упомяни Redux Toolkit как современный стандарт, но подчеркни важность понимания ручной реализации. Приведи пример тестирования reducer’а. Покажи знание best practices: иммутабельность, обработка default case, типизация payload.

Что проверяет интервьюер

  • Понимание core концепции Redux: reducer как чистая функция
  • Знание TypeScript: discriminated unions, type narrowing в switch
  • Умение писать тесты для state management
  • Понимание trade-off между switch-case и builder pattern
  • Знание современных практик (Redux Toolkit) и умение объяснить legacy код

Типичные ошибки

  • Мутация state вместо возврата нового объекта
  • Игнорирование default case (должен возвращать state без изменений)
  • Отсутствие типизации payload в TypeScript (использование any)
  • Путаница между action creator и action объектом
  • Неправильная обработка вложенных структур (нужно копировать каждый уровень)
  • Забывают про return state в default, что ломает инициализацию

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью