Closed
Description
TypeScript Version: 3.4.1, 3.5.1
Search Terms: regression, ReturnType, parameter, inference
Code
interface Mapper<HandledInputT, OutputT> {
(name : string, mixed : HandledInputT) : OutputT,
}
export type IsPipeable<
FromF extends Mapper<any, any>,
ToF extends Mapper<any, any>
> = (
ToF extends Mapper<infer HandledInputT, any> ?
(
ReturnType<FromF> extends HandledInputT ?
true :
false
) :
false
);
export type AssertPipeable<
FromF extends Mapper<any, any>,
ToF extends Mapper<any, any>
> = (
IsPipeable<FromF, ToF> extends true ?
ToF :
[ReturnType<FromF>, "is not pipeable"]
);
declare function pipe<
F0 extends Mapper<unknown, any>,
F1 extends Mapper<any, any>
> (
f0 : F0,
f1 : AssertPipeable<F0, F1>
): void;
declare function literal<ArrT extends (string | number | boolean | bigint | null | undefined)[]>(
...arr: ArrT
): (
Mapper<unknown, ArrT[Extract<keyof ArrT, number>]>
);
declare const b: Mapper<"0" | "1" | 0 | 1 | "false" | "true", boolean>
//TS suddenly thinks the first arg is Mapper<unknown, any>.
//It is actually Mapper<unknown, "0" | "1" | 0 | 1 | "false" | "true">.
pipe(
//TS knows this is Mapper<unknown, "0" | "1" | 0 | 1 | "false" | "true">
literal("0", "1", 0, 1, "false", "true"),
/*
Expected: works.
Actual:
Argument of type 'Mapper<0 | "0" | "1" | 1 | "false" | "true", boolean>'
is not assignable to parameter of type '[any, "is not pipeable"]'.
Succeeds with 3.3.3,
Fails with 3.4.1,
Fails with 3.5.1
*/
b
);
const a = literal("0", "1", 0, 1, "false", "true");
//TS now knows the first arg is Mapper<unknown, "0" | "1" | 0 | 1 | "false" | "true">
pipe(
a,
/*
This works.
`a` is literally the same type as
`literal("0", "1", 0, 1, "false", "true")`.
Why would the first pipe() call fail,
but the second one succeed?
Succeeds with 3.3.3,
Succeeds with 3.4.1,
Succeeds with 3.5.1
*/
b
);
Expected behavior:
The below should work,
pipe(
literal("0", "1", 0, 1, "false", "true"),
b
);
Actual behavior:
It used to work but does not work now.
Playground Link: Playground
Related Issues:
I feel like it is related to #29133 somehow. Because I have ReturnType<>
being used in a parameter again. But it's somewhat different this time in that the first argument is not an anonymous function "literal" I created. It's a function given by another function.