Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redux Sagas, TypeScript, and call?

As a TypeScript and redux-thunk user, I am curious about the benefits offered by redux-saga. I'd like to give it a shot but am concerned about the call function and the apparent loss of type safety.

If I do this:

function* invalidateReddit(): SagaIterator {
  while (true) {
    const {reddit} = yield take(actions.INVALIDATE_REDDIT)
    yield call( fetchPosts, reddit )
  }

The compiler will not be able to check calls to fetchPosts. So if I changed the signature to not include the argument...

function fetchPosts() {
  // anything here...
}

The invalidateReddit function, which depends on fetchPosts, should fail to compile but it will not because call evaluates my code for me. Is there an established pattern for using this without sacrificing type safety?

UPDATE: The PR at https://github.com/redux-saga/redux-saga/pull/740 looks like it attempts to solve this problem. I will leave this open until it can be closed with a solution.

like image 806
subvertallchris Avatar asked Jan 16 '17 16:01

subvertallchris


1 Answers

Because TypeScript won't complain about excess variables you passed to a function.

As the type declaration per se, https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/redux-saga/index.d.ts#L75

export function call<T1, T2, T3>(fn: EffectFunction<T1, T2, T3>, arg1?: T1, arg2?: T2, arg3?: T3, ...rest: any[]): Effect;

If you pass a function with arity less than 3 to call, all the type parameter will be inferred to {}, the top type of TS. So basically every thing will be assignable in such call call(zeroArityFunc, anything).

At runtime, excess argument won't cause error, so your code should be fine. If fetchPosts does require argument, then the type parameter for it will be inferred and a compiler error will be raised.

like image 91
Herrington Darkholme Avatar answered Sep 30 '22 20:09

Herrington Darkholme