10000 Intersecting discriminated union breaks type narrowing · Issue #9919 · microsoft/TypeScript · GitHub
[go: up one dir, main page]

Skip to content
Intersecting discriminated union breaks type narrowing #9919
Closed
@gcnew

Description

@gcnew

TypeScript Version: nightly (2.0.0-dev.201xxxxx)

Code

type ToString = {
    toString(): string;
}

type BoxedValue = { kind: 'int',    num: number }
                | { kind: 'string', str: string }

type IntersectionFail = BoxedValue & ToString

type IntersectionInline = { kind: 'int',    num: number } & ToString
                        | { kind: 'string', str: string } & ToString

function getValueAsString(value: IntersectionFail): string {
    if (value.kind === 'int') {
        // Property 'num' does not exist on type '({ kind: "int"; num: number; } | { kind: "string"; str: string; }) & { toString(): string; }'.
        return '' + value.num;
    }

    // Property 'str' does not exist on type '({ kind: "int"; num: number; } | { kind: "string"; str: string; }) & { toString(): string; }'.
    return value.str;
}

If a discriminated union is enhanced via intersection, type narrowing based on the discrimination field starts to fail. This behaviour is not exhibited if a new discriminated union is created with the intersection being inlined into each of the respective options.

The function getValueAsString(value: IntersectionFail): string fails to compile, while getValueAsString(value: IntersectionInline): string compiles just fine. Unfortunately, it is IntersectionFail that is the result of natural program evolution.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FixedA PR has been merged for this issueSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0