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.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4