I expect the result type of a call effect with generic arguments to be propagated.
However, this does not work:
function* wrappedCall<Args extends any[], RT>(
saga: (...args: Args) => SagaIterator<RT>,
...args: Args
): SagaIterator<RT> {
return yield* call(saga, ...args); // Type 'SagaReturnType<(...args: Args) => SagaIterator<RT>>' is not assignable to type 'RT'.
}
Changing the type of the arguments to any[] allows the result type to propagate:
function* wrappedCall<RT>(
saga: (...args: any[]) => SagaIterator<RT>,
...args: any[]
): SagaIterator<RT> {
return yield* call(saga, ...args); // Result type is RT as expected
}
The problem comes from the definition of SagaReturnType:
export type SagaReturnType<S extends Function> =
S extends (...args: any[]) => SagaIterator<infer RT> ? RT :
S extends (...args: any[]) => Promise<infer RT> ? RT :
S extends (...args: any[]) => infer RT ? RT :
never;
When S is the type of a function whose arguments are a constrained type variable, typescript cannot compare any[] against the type variables and is unable to decide the conditional types.
The following code illustrates this limitation in the type system:
type IsVoid<T extends void> = T extends void ? true : false;
function foo<U extends void>(): [IsVoid<void>, IsVoid<U>, IsVoid<U>] {
return [true, true, false];
}
Parameterizing SagaReturnType over Args fixes the problem by avoiding the comparison between any[] and a constrained type variable. The following declarations fix the initial wrapped call example above:
This pull request copies and adapts the definition of SagaReturnType from @redux-saga/core as outlined above and makes the necessary changes throughout the type definitions.
I expect the result type of a call effect with generic arguments to be propagated.
However, this does not work:
Changing the type of the arguments to
any[]
allows the result type to propagate:The problem comes from the definition of
SagaReturnType
:When
S
is the type of a function whose arguments are a constrained type variable, typescript cannot compareany[]
against the type variables and is unable to decide the conditional types.The following code illustrates this limitation in the type system:
Parameterizing
SagaReturnType
over Args fixes the problem by avoiding the comparison betweenany[]
and a constrained type variable. The following declarations fix the initial wrapped call example above:This pull request copies and adapts the definition of
SagaReturnType
from@redux-saga/core
as outlined above and makes the necessary changes throughout the type definitions.