Skip to content

Narrowing a type union with user-defined type guard #12235

Closed
@lukaw3d

Description

@lukaw3d

TypeScript Version: >= 2.0.2

Code

getResults1([]);
getResults1({data: []});

getResults2([]);
getResults2({data: []});


type Result = {value: string}
type Results = Result[];


function isResponseInData<T>(value: T | { data: T}): value is { data: T } {
    return value.hasOwnProperty('data');
}
function getResults1(value: Results | { data: Results }): Results {
    // error TS2322: Type 'Results | {data: Results}' is not assignable to 'Results'
    return isResponseInData(value) ? value.data  // value: {data: Results}
                                   : value;      // value: Results | {data: Results}   !!
}


function isPlainResponse<T>(value: T | { data: T}): value is T {
    return !value.hasOwnProperty('data');
}
function getResults2(value: Results | { data: Results }): Results {
    // Good
    return isPlainResponse(value) ? value        // value: Results
                                  : value.data;  // value: {data: Results}
}

Expected behavior:
Expected both getResults1 and getResults2 to compile fine, as they did in [email protected] and [email protected].

Actual behavior:
getResults1 doesn't compile, because value's type doesn't get narrowed in versions from [email protected] forward (still an issue in 2.2.0-dev.20161114).

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