> Как проверять конкретный 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:
TYPESCRIPTtype 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 };// Reducerfunction 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, что ломает инициализацию
> Похожие задачи по frontend
Почему у объекта arguments в JavaScript нет метода shift
Что такое псевдомассив arguments в JavaScript?
Что такое TypeScript и чем он отличается от JavaScript
В чем преимущества статической типизации TypeScript по сравнению с динамической типизацией JavaScript?
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью