Skip to content

Property goes undetermined on discriminated union #9977

@saschanaz

Description

@saschanaz

TypeScript Version: 2.0 beta

Code

"use strict";

type IDLMemberTypes = OperationMemberType | ConstantMemberType;

interface IDLTypeDescription {
    origin: string;
}

interface InterfaceType {
    members: IDLMemberTypes[];
}

interface OperationMemberType {
    type: "operation";
    idlType: IDLTypeDescription | null;
}

interface ConstantMemberType {
    type: "const";
    idlType: string;
}
// case 1
function insertInterface(callbackType: InterfaceType) {
    for (const memberType of callbackType.members) {
        if (memberType.type === "const") {
            memberType.idlType
            // type of idlType: string, no error
        }
        else if (memberType.type === "operation") {
            memberType.idlType.origin;
            // type of idlType: IDLTypeDescription at least on mouse hover
            /*
            Mutually incompatible messages appear simultaneously:

            1. (property) IDLTypeDescription.origin: string
            2. Property 'origin' does not exist on type 'string'
            */
            (memberType.idlType as IDLTypeDescription);
            // Error: Type 'string' cannot be converted to type 'IDLTypeDescription'
        }
    }
}
// case 2
function insertInterface2(callbackType: InterfaceType) {
    for (const memberType of callbackType.members) {
        if (memberType.type === "operation") {
            memberType.idlType.origin
            // type of idlType: IDLTypeDescription
            // type of origin: string, no error
        }
    }
}
// case 3
function foo(memberType: IDLMemberTypes) {
    if (memberType.type === "const") {
        memberType.idlType
        // type of idlType: string, no error
    }
    else if (memberType.type === "operation") {
        memberType.idlType.origin
        // type of idlType: IDLTypeDescription
        // type of origin: string, no error
    }
}

Expected behavior:

memberType.idlType.origin should be string in both case thanks to the type guard

Actual behavior:

Type guard confuses the type of idlType

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScriptFixedA PR has been merged for this issue

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions