redux-toolkit icon indicating copy to clipboard operation
redux-toolkit copied to clipboard

The inferred type of 'X-Slice' cannot be named without a reference to '@reduxjs/toolkit/node_modules/immer/dist/internal'. This is likely not portable. A type annotation is necessary.

Open marinsokol5 opened this issue 5 months ago • 0 comments

Hey folks,

Opening as a duplicate of https://github.com/reduxjs/redux-toolkit/issues/1806 since I can't comment on that thread.

It's indeed a small type issue, and I am opening it just because of the high bar for your existing types. If this was another library, I would not even bother.

But effectively, I agree with https://github.com/reduxjs/redux-toolkit/issues/1806#issuecomment-1925437633, and v2.2.7 does not solve the problem.

Link to TS playground

Copying the example code from https://redux-toolkit.js.org/api/createslice:

import { createSlice } from '@reduxjs/toolkit'
import type { PayloadAction } from '@reduxjs/toolkit'

interface CounterState {
  value: number
}

const initialState = { value: 0 } satisfies CounterState as CounterState

export const counterSlice = createSlice({
  name: 'counter',
  initialState,
  reducers: {
    increment(state) {
      state.value++
    },
    decrement(state) {
      state.value--
    },
    incrementByAmount(state, action: PayloadAction<number>) {
      state.value += action.payload
    },
  },
})

into https://www.typescriptlang.org/play, transpiles into

import type { PayloadAction } from '@reduxjs/toolkit';
interface CounterState {
    value: number;
}
export declare const counterSlice: import("@reduxjs/toolkit").Slice<CounterState, {
    increment(state: import("immer").WritableDraft<CounterState>): void;
    decrement(state: import("immer").WritableDraft<CounterState>): void;
    incrementByAmount(state: import("immer").WritableDraft<CounterState>, action: PayloadAction<number>): void;
}, "counter", "counter", import("@reduxjs/toolkit").SliceSelectors<CounterState>>;
export {};

That is quite problematic, because the WritableDraft will depend on root-level immer version, not the one used by RTK. That works only if those are the same, else folks would get such (rightful) compilation errors from above. This happens because WritableDraft is inferred from Draft but not exported.

If it was this would get transpiled to much nicer

import("@reduxjs/toolkit").WritableDraft

which would then lead to the immer attached to RTK, which may be the root one, and may be the "node_modules/RTK/node_modules/immer".

marinsokol5 avatar Jun 18 '25 16:06 marinsokol5