Skip to content

Discriminated union fails in if statementsΒ #46763

Closed
@imdavidmin

Description

@imdavidmin

Bug Report

πŸ”Ž Search Terms

Discriminated union, if, if condition, conditional statements

πŸ•— Version & Regression Information

4.4.4

⏯ Playground Link

Playground Link

πŸ’» Code

type FailedTest = { status: '1' | '3' } | FailedTestSpecial
type FailedTestSpecial = { status: '2', data: '2' }
const FailedInput = [] as Array<FailedTest>
const FailedOutput = [] as Array<FailedTestSpecial>

if (FailedInput[0].status == '1' || FailedInput[0].status == '3') {
  FailedInput[0].data // This works as exected.
} else {
  FailedInput[0].status
  FailedOutput.push(FailedInput[0])
}


// Declared now as status 1 and 3 separately
type PassedTest = { status: '1' } | PassedTestSpecial | { status: '3' }
type PassedTestSpecial = { status: '2', data: '2' }
const passedInput = [] as Array<PassedTest>
const passedOutput = [] as Array<PassedTestSpecial>

if (passedInput[0].status == '1' || passedInput[0].status == '3') {
  passedInput[0].data // This works as exected.
} else {
  passedInput[0].status
  passedOutput.push(passedInput[0])
}

πŸ™ Actual behavior

In the failed test, at else in the if block, Typescript understands the status key could only be '2' (mouse hover over .status shows the info), but could not infer from this that the type must be FailedTestSpecial type.
In the passed test, with only the change in how PassedTest is defined by separating {status: '1' | '3'} to {status: '1'} | {status: '3'}, Typescript can now tell the discriminated union in if block.

πŸ™‚ Expected behavior

FailedTest to pass, by inferring the type must be FailedTestSpecial type.

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions