Not planned
Description
Bug Report
π Search Terms
Return Inference Object Unions Multiple Return Types
π Version & Regression Information
Seeing it from version 3+
β― Playground Link
Playground link with relevant code
π» Code
type X = {
a: number
} | {
a: number,
b: string
}
// Problematic Case
declare const value: X;
declare const bool: boolean;
const fn = () => {
if(bool) return undefined;
return value;
}
const resultBad = fn();
if(resultBad && "b" in resultBad){
parseInt(resultBad.b); // type error, b unknown
}
// Explicit return value, Unproblematic
const fnExplicit = (): X|undefined => {
if(bool) return undefined;
return value;
}
const resultExplicit = fnExplicit();
if(resultExplicit && "b" in resultExplicit){
parseInt(resultExplicit.b); // ok
}
// Unproblematic case
const branchlessFn = () => {
return value;
}
const resultGood = branchlessFn();
if("b" in resultGood){
parseInt(resultGood.b); // ok
}
π Actual behavior
When a function has multiple return values, and one of the possible return values is
a union of objects, the return type is inferred as the common properties between that
object, instead of the full union
π Expected behavior
I would expect the object to be the full union, e.g. I would expect the inferred return value of fn
to be the same as the explicitly typed value of fnExplicit
Metadata
Metadata
Assignees
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
MartinJohns commentedon Jul 14, 2023
This is the expected behaviour due to "subtype reduction". See also: Issue search for "subtype reduction"
As per Ryan wrote: #50171 (comment)
guillaumebrunerie commentedon Jul 15, 2023
Your type
X
is already equivalent to{a: number}
because any value of type{a: number, b: string}
is assignable to{a: number}
. If you use a discriminated union forX
instead, the issue disappears:typescript-bot commentedon Jul 20, 2023
This issue has been marked as "Duplicate" and has seen no recent activity. It has been automatically closed for house-keeping purposes.