Skip to content

Discriminated union does not work with string literal types #37650

Closed

Description

@alex-kinokon

TypeScript Version: 3.8.3

Search Terms:

Code

const $type: "@type" = "@type"
type A = { ["@type"]: "A", a: boolean }
type B = { ["@type"]: "B", b: boolean }
type C = A | B

declare const c: C;
switch (c[$type]) {
    case "A":
        c.a; // <-- Property 'a' does not exist on type 'B'.(2339)
}

switch (c["@type"]) {
    case "A":
        c.a;
}

Expected behavior:
No error.

Actual behavior:
Property 'a' does not exist on type 'B'.(2339)

Playground Link:
Playground

Related Issues:
Can’t find any so far.

Activity

  1. RyanCavanaugh commented on Apr 1, 2020

    @RyanCavanaugh
    Member
  2. sandersn commented on Apr 1, 2020

    @sandersn
    Member

    Performance limitation; it's too expensive to put a control flow node on every element access -- creating it uses too much space and walking over it uses too much time. The decision to create a flow node is made syntactically, just after parsing, so there's no type information to guide it.

    We have made similarly expensive expansions to control flow analysis before, like the nodes we add to support assert narrowing. But this feature isn't as useful, I think.

  3. sandersn commented on Apr 1, 2020

    @sandersn
    Member

    Discussion is here, including a link back to the original bug: #31478

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Design LimitationConstraints of the existing architecture prevent this from being fixedNeeds InvestigationThis issue needs a team member to investigate its status.

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions