Vinay Sharma
Vinay Sharma

Reputation: 3807

Redux Saga: Type 'unknown' is not assignable to type 'ServerResponse'

Problem Statement:

I'm unable to specify type for the yield call(). The yield is calling an API that fetches some data from server. The of data type is ServerResponse. What I want to do is specify type as follows:

const response: ServerResponse = yield serverCall();

But I Typescript throws this error: Redux Saga: Type 'unknown' is not assignable to type 'ServerResponse'.

Code:

function* serverSaga(): Generator {
  try {
    // TS throws error here;
    const response: ServerResponse = yield serverCall();
    ...
    ...
  } catch (err) {
    ...
  }
}

const serverCall = async (): Promise<ServerResponse> => {
  try {
    const response =  await ...
    return response;
  } catch (err) {
    ...
  }
};

Upvotes: 1

Views: 3998

Answers (3)

Raphael Souza
Raphael Souza

Reputation: 737

I used the Generator<AllEffect<ForkEffect<never>>> typing for the function. and it worked.

export default function* rootSaga(): Generator<AllEffect<ForkEffect<never>>> {
   const response = yield all([
    takeLatest(RepositoriesTypes.LOAD_REQUEST, load)
  ]);
  return response;
}

Upvotes: 1

Kevin Carlos
Kevin Carlos

Reputation: 51

Everyone has provided good answers, but alternatively you could look into this library that helps alleviate this sort of issue. I've found it pretty useful for situations like this.

Upvotes: 1

zero298
zero298

Reputation: 26930

I believe you need to type your Generator generic, and should also be using call to actually call to the async function:

import {
  call,
  CallEffect
} from "redux-saga/effects";

function* serverSaga(): Generator<CallEffect<ServerResponse>, void, never> {
  try {
    // TS throws error here;
    const response: ServerResponse = yield call(serverCall);
    ...
    ...
  } catch (err) {
    ...
  }
}

const serverCall = async (): Promise<ServerResponse> => {
  try {
    const response =  await ...
    return response;
  } catch (err) {
    ...
  }
};

The actual types that the generic Generator wants can be considered with the following example. Complex sagas can make the generic kind of obtuse.

type MyGen = Generator<
  number, // Outgoing (what you might yield)
  boolean, // What could be returned
  string // Incoming (left side of yield)
>;

function* MySaga(): MyGen {
  let outgoing = 0;
  while (outgoing < 10) {
    outgoing++;
    const incoming: string = yield outgoing;
    console.log(incoming);
  }
  return true;
}

Upvotes: 4

Related Questions