Using TypeScript to ensure the correct typing for the return type of AsyncThunk when utilizing the 'unwrapResult' method from Redux Toolkit

Struggling to determine the appropriate return type for an AsyncThunkAction in order to utilize it with the unwrapResult method from Redux Toolkit (refer to: Redux Tookit: Unwrapping Result Actions):

Here is how the Async thunk is declared in the Slice:

export
 const createChannel = createAsyncThunk<
  { id: string },
  ChannelReqDto,
  InjectedAxiosClientType
>("channel/createChannel", async (req, thunkApi) => {
  const result = await thunkApi.extra.client.post(
    `/store/${req.storeId}/channels`,
    {
      category: req.category,
      group: req.group,
      name: req.name,
      rules: [],
    }
  );
  return result.data;
});

Usage within a React Component:

const newChannel = await dispatch(
    createChannel({
        name: name,
        group: group,
        category: category,
        storeId: storeIdParam,
        rules: [],
    })
);
const result = unwrapResult(newChannel);

Error encountered in TypeScript:

TS2345: Argument of type 'AsyncThunkAction<{ id: string; }, ChannelReqDto, InjectedAxiosClientType>' is not assignable to parameter of type 'UnwrappableAction'.   Property 'payload' is missing in type 'AsyncThunkAction<{ id: string; }, ChannelReqDto, InjectedAxiosClientType>' but required in type 'UnwrappableAction'.

The expected result type must extend the interface UnwrappableAction, but I'm having trouble resolving this without using ts-ignore:

export declare function unwrapResult<R extends UnwrappableAction>(action: R): UnwrappedActionPayload<R>;

Answer №1

During a discussion in the Reactiflux chat, I received valuable insight from @acemarke:

To properly utilize typed dispatch in Redux, it is important to declare it within the redux store (such as store.tsx):

export type AppDispatch = typeof store.dispatch;
export const useAppDispatch = () => useDispatch<AppDispatch>();
  • The default behavior of `store.dispatch()` is to return the action passed in
  • Middleware can alter this behavior by returning something else instead
  • The thunk middleware exemplifies this by returning the value of your thunk function
  • The base Dispatch type is unaware of the presence of the thunk middleware, causing it to expect the thunk function itself as the return value
  • It is crucial to note that the thunk function does not have an unwrap-pable payload field
  • By transitioning to the custom AppDispatch type, TypeScript now recognizes that "the return type of dispatch is whatever this thunk function returns"

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Set up Admin SDK using appropriate credentials for the given environment

As someone new to Node.js, Firebase Cloud Functions, and TypeScript, my objective is to create a cloud function that acts as an HTTP endpoint for clients to authenticate with Firebase. The desired outcome is for the cloud function to provide a custom acces ...

Create and save data to a local file using Angular service

I am facing an issue with my Angular service: import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; import { person } from '../interfaces/iperson ...

Is there a way to display a variety of images on separate divs using *ngFor or another method?

I have created a custom gallery and now I would like to apply titration on the wrapper in order to display a different image on each div. Currently, my code is repeating a single image throughout the entire gallery. HTML <div class="wrapper" ...

Exploring Angular14: A guide to efficiently looping through the controls of strictly typed FormGroups

Currently, I am working on upgrading my formGroups to be strictly typed in Angular v14. Within my FormGroup, there is a specific block of logic that iterates through all the controls and performs an action (this part is not crucial as I am facing issues be ...

Exploring ways to conduct a thorough scan of object values, inclusive of nested arrays

My goal is to extract all values from an object. This object also includes arrays, and those arrays contain objects that in turn can have arrays. function iterate(obj) { Object.keys(obj).forEach(key => { console.log(`key: ${key}, value: ${o ...

How does [name] compare to [attr.name]?

Question regarding the [attr.name] and [name], I am utilizing querySelectorAll in my Typescript as shown below: this._document.querySelectorAll("input[name='checkModel-']") However, when I define it in the HTML like this: <input [name]="check ...

Updating the status of various sections with Redux toolkit

Is it possible to update the state of a store, which consists of multiple slices, with a new state in React using Redux Toolkit? While you can revert the entire store to its initial state using extraReducers, is it also possible to change the state to som ...

The data remains undefined even after being initialized in the constructor

My goal is to extract queryParams from a URL and leverage that information to resolve data in the following manner: data = { searchValue: null || undefined }; constructor(private http: HttpClient, private route: ActivatedRoute) { route.queryParams.su ...

The variable "theme" is referenced prior to being initialized

https://i.stack.imgur.com/QL0pa.png One of the variables in my code, theme, is set to be assigned a value from a for loop: let theme: Theme for (const themeObj of themeList) { const [muiThemeName, muiTheme] = Object.entries(themeObj)[0]!; if (muiThem ...

Mapping nested values from a Typescript object to properties of a JSON object

Within the scope of a current project I am involved in, we have opted for utilizing the Angular toolset identified as formly to dynamically generate our forms. The present configuration of the form is hardcoded into a Typescript object denoted as mockForm ...

Validating forms using TypeScript in a Vue.js application with the Vuetify

Currently, I am attempting to utilize Vue.js in conjunction with TypeScript. My goal is to create a basic form with some validation but I keep encountering errors within Visual Studio Code. The initial errors stem from my validate function: validate(): v ...

Impact when returning a React.FC Component

Using React, I have encountered a challenge with my site: I have a function that generates a Card component displaying information about my store's products (#1). To display this on the screen, I map through the array returned by the backend and pass ...

The pathway specified is untraceable by the gulp system

Hey there, I've encountered an issue with my project that uses gulp. The gulpfile.js suddenly stopped working without any changes made to it. The output I'm getting is: cmd.exe /c gulp --tasks-simple The system cannot find the path specified. ...

Is it possible to determine when a component has completed its rendering process in Angular?

I am currently working on an Angular application where I have a page component that contains several subcomponents. Each subcomponent is set up to fetch data from an API in the ngOnInit method, causing a layout shift issue as they load at different speeds ...

What exactly does the $any() type cast in Angular do and how is it used?

While browsing the Angular.io site, I came across this title: The $any() type cast function There are instances where a binding expression may trigger a type error during AOT compilation and it is not possible or difficult to fully specify the type. To re ...

What is the best way to pass down SectionList prop types in TypeScript when using React?

I am working on creating a wrapper for SectionList in React Native that needs to accept all the standard props of SectionList along with some custom ones. How can I set up typescript to accommodate this? Here is what I have tried: import React from &apos ...

Dynamically change or reassign object types in TypeScript

Check out the example you can copy and test in TypeScript Playground: class GreetMessage { message: {}; constructor(msg: string) { let newTyping: { textMsg: string }; // reassign necessary this.message = newTyping; this.message.textMsg = msg; ...

Angular: Defining variables using let and var

When working with TypeScript and JavaScript, we typically use either let or var to declare a variable. However, in Angular components, we do not use them even though Angular itself uses TypeScript. For instance, export class ProductComponent implements OnI ...

Angular 4 Operator for adding elements to the front of an array and returning the updated array

I am searching for a solution in TypeScript that adds an element to the beginning of an array and returns the updated array. I am working with Angular and Redux, trying to write a reducer function that requires this specific functionality. Using unshift ...

Angular - passing information to a nested component

Within my application, I have a main component along with three sub-components. I am passing data to these three sub-components and using setTimeout to manage the timing of the data being sent. The first sub-component displays for 5000 milliseconds. The ...