How to fix useSelector must return the same type in every case in React

ReactINTERMEDIATEMEDIUMUpdated Dec 10, 2025· 87 views

This TypeScript error occurs when the useSelector hook from React Redux returns inconsistent types across different execution paths. It often happens when using equality functions like shallowEqual or when selector functions have conditional return types. The error prevents proper type inference and can lead to runtime issues.

Quick fix

Fixes useSelector must return the same type in every case

// ❌ Bad: Returns different types
const selectValue = (state: RootState) => {
  if (state.someCondition) {
    return state.data.value; // number
  }
  return null; // null
};

// ✅ Good: Always returns the same type
const selectValue = (state: RootState): number | null => {
  if (state.someCondition) {
    return state.data.value;
  }
  return null;
};
  1. Ensure your selector function has a consistent return type
  2. Use typed hooks instead of raw useSelector with equality functions
  3. Avoid equality functions when possible
  4. Update your React Redux type definitions
react — error
// ❌ Bad: Returns different types
const selectValue = (state: RootState) => {
if (state.someCondition) {
return state.data.value; // number
}
return null; // null
};
// ✅ Good: Always returns the same type
const selectValue = (state: RootState): number | null => {
if (state.someCondition) {
return state.data.value;
}
return null;
};
useSelector must return the same type in every case

What this error means

The "useSelector must return the same type in every case" error is a TypeScript compilation error that arises when TypeScript cannot guarantee that a useSelector hook will always return the same type of value. This typically happens when the selector function passed to useSelector has multiple return types based on conditions, or when using equality comparison functions that interfere with TypeScript's ability to infer consistent return types. React Redux relies on consistent typing to ensure type safety throughout your application.

Typical symptoms

  • TypeScript compilation fails with error: "useSelector must return the same type in every case"
  • The useSelector hook returns type `any` when using shallowEqual or other equality functions
  • Auto-completion and type checking for the selected value stop working in your IDE
  • The error appears after upgrading React Redux to version 9.x or later
  • Type inference works fine when removing the second argument (equality function) from useSelector

Common causes

  1. Using shallowEqual or custom equality functions as the second argument to useSelector can interfere with TypeScript type inference
  2. Selector functions that return different types based on conditions (e.g., returning undefined in some cases)
  3. Incorrect or missing type definitions for the Redux store state
  4. Using useSelector.withTypes() with equality functions in React Redux versions 9.1.0+
  5. Mismatch between the expected return type of the selector and what TypeScript can infer

How to fix "useSelector must return the same type in every case"

1Ensure your selector function has a consistent return type

Check that your selector function always returns the same type, regardless of conditions. Avoid returning undefined or different types in different branches.

typescript
// ❌ Bad: Returns different types
const selectValue = (state: RootState) => {
  if (state.someCondition) {
    return state.data.value; // number
  }
  return null; // null
};

// ✅ Good: Always returns the same type
const selectValue = (state: RootState): number | null => {
  if (state.someCondition) {
    return state.data.value;
  }
  return null;
};
2Use typed hooks instead of raw useSelector with equality functions

Create pre-typed versions of useSelector using React Redux's .withTypes() method or the traditional TypedUseSelectorHook approach.

typescript
// Using .withTypes() (React Redux v9.1.0+)
import { useSelector } from 'react-redux';
import type { RootState } from './store';

export const useAppSelector = useSelector.withTypes<RootState>();

// In your component
const value = useAppSelector(selectValue); // No second argument needed

// If you need equality comparison, consider alternatives
3Avoid equality functions when possible

If you're using shallowEqual to prevent unnecessary re-renders, consider using memoized selectors with Reselect instead, which provides better TypeScript support.

typescript
import { createSelector } from '@reduxjs/toolkit';

const selectData = (state: RootState) => state.some.data;
const selectFilter = (state: RootState) => state.some.filter;

export const selectFilteredData = createSelector(
  [selectData, selectFilter],
  (data, filter) => data.filter(item => item.matches(filter))
);

// This selector is automatically memoized and has proper typing
const filteredData = useAppSelector(selectFilteredData);
4Update your React Redux type definitions

Ensure you have the latest type definitions installed. For React Redux v9+, types are included in the package, but you might need to update your @types/react-redux if you're on an older version.

bash
npm update react-redux @types/react-redux

Or if using yarn:

bash
yarn upgrade react-redux @types/react-redux
5Use explicit type annotations for complex selectors

When your selector logic is complex, provide explicit return type annotations to help TypeScript understand the expected output.

typescript
interface ComplexResult {
  items: Item[];
  total: number;
  hasMore: boolean;
}

const selectComplexData = (state: RootState): ComplexResult => {
  // Complex logic here
  return {
    items: state.data.items,
    total: state.data.total,
    hasMore: state.data.hasMore
  };
};

// TypeScript now knows the exact return type
const complexData = useSelector(selectComplexData);

Advanced notes

This issue became more prominent in React Redux v9.1.0+ due to changes in how TypeScript infers types with the .withTypes() method. The underlying problem is that TypeScript's type system has limitations when dealing with higher-order functions that accept equality comparators. For advanced use cases, consider using the useSelector hook without equality functions and implement performance optimizations at the selector level using Reselect's memoization capabilities. Additionally, ensure your Redux store state is properly typed using TypeScript's RootState pattern as documented in the official Redux Toolkit documentation.

Frequently asked questions

What does "useSelector must return the same type in every case" mean?
The "useSelector must return the same type in every case" error is a TypeScript compilation error that arises when TypeScript cannot guarantee that a useSelector hook will always return the same type of value. This typically happens when the selector function passed to useSelector has multiple return types based on conditions, or when using equality comparison functions that interfere with TypeScript's ability to infer consistent return types. React Redux relies on consistent typing to ensure type safety throughout your application.
How do I fix "useSelector must return the same type in every case"?
This TypeScript error occurs when the useSelector hook from React Redux returns inconsistent types across different execution paths. It often happens when using equality functions like shallowEqual or when selector functions have conditional return types. The error prevents proper type inference and can lead to runtime issues.
What causes "useSelector must return the same type in every case"?
Using shallowEqual or custom equality functions as the second argument to useSelector can interfere with TypeScript type inference Selector functions that return different types based on conditions (e.g., returning undefined in some cases) Incorrect or missing type definitions for the Redux store state
Is the "useSelector must return the same type in every case" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading