When resolving incompatible signatures, skip callbacks with never
arguments [ts(2349)]
#42487
Closed
5 tasks done
Suggestion
TypeScript sometimes infers empty arrays as having type
never[]
. Usually, this doesn't cause problems, until it gets unioned with another type, and you try to call it as a function/method:In this example, since the
[]
is typed asnever[]
, the.map
method has a union type with two incompatible types; one possibility is astring
,number
,string[]
argument list returning a genericU
, and the other is anever
,number
,never[]
argument list returning a genericU
.Right now, tsc doesn't distinguish between the two; since they're incompatible, it raises
ts(2349)
. This can make it difficult to write nicely-chainable union values, since the inferred values for "empty" or "impossible" variants prevent type inference from working.However, there's a very easy reason to see why the first overload should be preferred: values of type
never
shouldn't exist, so a function asking for anever
will never be called.While applying this rule in general is too extreme (since it would likely open up many soundness holes), we can add a small exception to
ts(2349)
: before rejecting the call for having incompatible callback types, check to see if any argument is a callback expectingnever
as any argument. If so, replace that callback with the most-general function type,(...args: unknown[]) => never
. Then attempt to type-check with this type.We can see that the existing type machinery can handle the code after this "fix":
This change is very narrow, since it only applies to code that:
ts(2349)
never
In particular, since it only affects code that today fails to compile, it can't introduce new breaking changes.
Despite being fairly narrow, it should help out inference for many common functions, especially related to empty arrays and other empty collections, including
.map
,.filter
,.flatMap
,.reduce
, etc.🔍 Search Terms
Vaguely related, but broader/different from this proposal: #40157
never
Union of subtypes should be usable as the supertype #38048List of keywords you searched for before creating this issue. Write them down here so that others can find this suggestion more easily and help provide feedback.
✅ Viability Checklist
My suggestion meets these guidelines:
📃 Motivating Example
💻 Use Cases
Making "chaining" libraries more ergonomic, especially when dealing with results.
Improves types for various array methods.
Also applies to other collections, like
new Set([])
having typeSet<never>
; this makes.forEach
callable on a union value withnew Set([])
as one possible alternative.The text was updated successfully, but these errors were encountered: