Skip to content

Type narrowing not working for unions of tuples with object literals #31613

Open
@squidfunk

Description

@squidfunk

It's not possible to narrow unions of tuples with object literals

TypeScript Version: 3.4.5, 3.5.0-rc

Search Terms: tuple narrow object literals

Code:

Narrowing tuples with primitive types works as expected:

type X = ["a", "c"] | ["b", "b"]

function bar(x: X) {
  if (x[0] === "b") {
    return x[1] === "c" // correctly narrows to "c", shows "condition always false"
  }
}

However, when the tuple contains object literals, narrowing doesn't work at all:

interface A { data: "a" }
interface B { data: "b" }
interface C { data: "c" }

type Y = [A, C] | [B, B]

function foo(y: Y) {
  if (y[0].data === "b") {
    return y[1].data === "c" // incorrectly narrows to "c" | "b"
  }
}

Expected behavior:

The object literal within the tuple is correctly narrowed down to type B

Actual behavior:

The object literal is not narrowed, leaving it at type C | B.

Playground Link: Link

Related Issues:
#26323
#24120
#10530

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScriptDomain: Control FlowThe issue relates to control flow analysisNeeds ProposalThis issue needs a plan that clarifies the finer details of how it could be implemented.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions