Redux saga use Call effect with generic function type typescript

Viewed 1987

I'm currently using Redux-saga and typescript. But I don't know how to use call effect with generic function type in Typescript.

For eg. I have a function with generic type like this:

function identity<T>(arg: T): T {
    return arg;
}

And, in saga, I expect the code like this:

...
const result = yield call(identity<string>, "myString")
...

However the compiler shows errors. Of course, I can write

const result = yield call(identity, "myString")

But it's not my expectation. How can I know is there any way/syntax to satisfies my above expectation?

3 Answers

Possible solution is to define type of identity function and use it to specialize call invocation.

type identityFunction<T> = (agr: T) => T;

And provide type to call function

yield call<identityFunction<string>>(identity, 'myString');

Now, if you try to call yield call<identityFunction<string>> with wrong arguments (also if signature of identity function will not match type identityFunction<T>), TypeScript will display error.

You can use module augmentation to add an additional typing to the "redux-saga/effects" module that is similar to the Function.apply typing:

import { CallEffect } from 'redux-saga/effects';

declare module 'redux-saga/effects' {
  export function call<A extends any[], R>(fn: (...args: A) => R, ...args: A): CallEffect<R>;
}

Make sure this is in a typescript file (*.ts), not a declaration file (*.d.ts).

Not sure why this isn't the official typing.

You can try saga return type SagaIterator

import { SagaIterator } from '@redux-saga/core';
import { put, select, call } from 'redux-saga/effects';
function identity<T>(arg: T): SagaIterator  {
...
  yield call([identityFunction<string>>],identity, 'myString');
...
}
Related