Description
Issue originally discovered by @eyelidlessness on Gitter.
TypeScript Version: 3.8.0-dev.20191123
Search Terms: generic
returntype
Code
declare const foo: <
R1,
F1 extends () => R1,
R2,
F2 extends (input: ReturnType<F1>) => R2
>(
f1: F1,
f2: F2
) => any
const f1 = () => ({ a: 'a' })
const f2 = (input: { a: string }) => ({ b: 'b' })
foo(f1, f2) // Good
const makeF1 = () => f1;
foo(makeF1(), f2) // Good
const makeF1p = <T>(t: T) => f1;
foo(
makeF1p(''),
f2 // Error WHY :(
);
const made = makeF1p('');
foo(
made, // This is fine
f2
)
Expected behavior:
Both foo()
calls should compile as the only difference is whether the result of a function call is assigned to a temporary first.
Actual behavior:
The first call to foo()
, where makeF1p()
is called inline, produces a type error at compile time. The second, where the return value of makeF1p()
is assigned to temp variable first, compiles fine. The error is:
Argument of type '(input: { a: string; }) => { b: string; }' is not assignable to parameter of type '(input: unknown) => unknown'.
Types of parameters 'input' and 'input' are incompatible.
Type 'unknown' is not assignable to type '{ a: string; }'.
It almost seems like the type parameter inference machinery is leaking outside the scope of the call expression or something? It's weird, at any rate.
Playground Link:
Related Issues: I didn't find any, but @jack-williams says #30215 might be the root cause.