How to use createAsyncThunk from Redux Toolkit with TypeScript correctly?
Asked Answered
C

2

5

I want to create a Redux slice for the users inside the project I work on. I have this code sandbox and I do not know why there is the following error on the fetchAll call in the MyButton.tsx file:

fetchAll(arg: any): AsyncThunkAction<unknown, any, {}>

Expected 1 arguments, but got 0.

createAsyncThunk.d.ts(107, 118): An argument for 'arg' was not provided.

I have similar code in the project I work on and it does not have this error. I expected this to work just as it does in other similar files.

The relevant files from the sandbox:

MyButton.tsx

import React from "react";
import { useDispatch } from "react-redux";
import { fetchAll } from "./redux/usersSlice";

export const MyButton = ({ children }: { children: any }) => {
  const dispatch = useDispatch();

  return (
    <button
      onClick={() => {
        dispatch(fetchAll()); // I get an error on this fetchAll() call
      }}
    >
      {children}
    </button>
  );
};

The definition of fetchAll

export const fetchAll = createAsyncThunk(
  "users/fetchAll",
  async (_: any, thunkAPI) => {
    const users = await new Promise((resolve, reject) => {
      resolve(["a", "b", "c"]);
    });

    return users;
  }
);

Update 1

If I call fetchAll(null) instead of fetchAll(), it works well.

Commiserate answered 14/6, 2021 at 10:47 Comment(0)
3
11

Use the void type if you don't want that argument. any forces an argument.

export const fetchAll = createAsyncThunk(
  "users/fetchAll",
  async (_: void, thunkAPI) => {
    const users = await new Promise((resolve, reject) => {
      resolve(["a", "b", "c"]);
    });

    return users;
  }
);
3d answered 14/6, 2021 at 12:34 Comment(2)
It works! Could you please explain how it works this way? I thought void is just a function return type. I read just the TS handbook. Thanks!Commiserate
The RTK types are just geared to accept "void" for that. Have been since before I took over most of the type maintenance, so I just kept it at that pattern.3d
N
5

And if you want to specify the types:

interface IThunkApi {
  dispatch: AppDispatch,
  state: IRootState,
}

export const fetchAll = createAsyncThunk<
string[], // return type
void, // args type
IThunkApi, // thunkAPI type
>("users/fetchAll", async (args, thunkAPI) => {
  const users = await new Promise((resolve, reject) => {
    resolve(["a", "b", "c"]);
  });
   return users;
});
Nightwalker answered 16/6, 2021 at 10:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.