Determine the type of a return value from dispatch

Viewed 1144

I'm coding a functional component in redux and I added a return values for a specific action.
The new value comes from a Promise so if the type is called Ival the return value will be of type Promise<Ival | null> (null in case the response failed).
My question is how do I determine the return type to Ival?

This is the action:

export const addVal = (data: IData) => async (dispatch: IDispatch): Promise<IVal | null> => {
  try {
    const resp = await api.vals.create(data);
    dispatch({ type: "CREATE_VAL", payload: resp });
    return resp;
  } catch (error) {
    dispatch({ type: "ERROR_MSG" ,payload: error });
    return null;
  }
};

this is the function I'm using the dispatch:

const createNewConnection = async (data: IData): Promise<void> => {

  try {
    const newVal: IVal | null = await dispatch(addVal(data));
    onValCreated(newVal);
  } catch (e) {
    onValCreated(null);
  }
};

The onValCreated function receives an IVal type as argument and this is the Error message:

"TS2559: Type '(dispatch: IDispatch) => Promise ' has no properties in common with type 'IVal'"

I tried on dispatch both:

// First try
const newVal: IVal | null = await dispatch<IVal | null>(addVal(data));

// Second try
const newVal: IVal | null = await dispatch<Promise<IVal | null>>(addVal(data));

But it didn't work

2 Answers

The await keyword basically "unpacks" a Promise in JS, awaiting a Promise<number>, will return you a number, means you already got the right approach. But from what it looks like, you tried to apply this rule at the wrong place. You don't have to await when calling, but when dealing with the returned value from the function (means: When passing parameters to onValCreated and not to dispatch). However the error message, gives you the dispatch function since this is where you get the "wrong type" from.

The fix is little, just do something like this and "unpack" the Promise with a "nested" await:

const newVal: IVal | null = await dispatch(await addVal(data));

the action returns a function that receives a dispatch as argument and then it returns the value I wanted. so what I did was create a const that execute the action and then execute this variable with the dispatch. finally it return a Promise of the type I wanted!

 try {
  const newVal = await addVal(data);
  onValCreated(await newVal(dispatch));
} catch (e) {
  onValCreated(null);
}
Related