Infer overloads instead of union returns from flow analysis #17747
Labels
Suggestion
An idea for TypeScript
Too Complex
An issue which adding support for may be too complex for the value it adds
Given the following code:
Today
flipFlop
is inferred as having a return type ofstring | number
. Intuitively though,flipFlop
is an overloaded function of type(x: number) => string & (x: string) => number
.Given that TypeScript already performs flow analysis in order to discover the union return type
string | number
, it seems like some useful information is being discarded. Specifically, when performing the analysis that yields a return type ofnumber | string
, it seems a shame to throw away the associated information thatx
is narrowed tonumber
in the exit block where the function's return type isstring
, and vice versa.If we instead utilize this information, it becomes possible to infer the much more accurate type
(x: number) => string & (x: string) => number
.In general, it might be nice if union parameters, overloaded functions, and control flow could be integrated more smoothly.
A function type with a union parameter
(x: number | string) => Date
is basically equivalent to the overloaded function(x: number) => Date & (x: string) => Date
. Similarly, a branched function with various return points (such asflipFlop
) is overloaded with respect to the return type.If the CFA treats each type in the union type of a parameter as a separate entry point, and solves the control flow for each indepenently, it should be possible to discover multiple independent mappings of input types to output type (i.e. overloads).
For functions with multiple parameters of union types, the overloads inferred must be a cartesian product of the unions. This can get expensive quickly, but some analysis of the function body to predict which types are actually discriminated against should allow "inert" unions that do not participate in control flow to be grouped together and treated as a single overload/entrypoint.
The text was updated successfully, but these errors were encountered: