Skip to content

Support type guards on property access expression #3812

@tinganho

Description

@tinganho

I just found out that property access expressions doesn't work on type predicate functions and instanceof type guards.

class A {
    propA: number;
}

class B {
    propB: number;
}
class C {
    propC: A;
}

declare function isA(p1: any): p1 is D;

interface D {
    a: A | B
    b: A | C;
}

let d: D;
if (isA(d.b)) {
    d.b.propA; //error
}

function foo(d: D) {
    if (d.b instanceof A) {
        d.b.propA // error
    }
}

I'm not sure if there is an easy fix on this problem. We are provided just a symbol when narrowing. That symbol represent the left most expression and then we walk up the if statement. There is no easy way of controlling symbol by symbol on each namespace in a property access expression in the if-statement-body. Because there is no info about the property access expression provided in getTypeOfSymbolAtLocation(symbol: Symbol, node: Node).

I also found that type assertion expressions are also not working in type predicate functions. But I will land a fix on that.

if (isA(<A>union)) {
    a = union;
}
if (isA(union as A)) {
    a = union;
}

Metadata

Metadata

Assignees

Labels

CommittedThe team has roadmapped this issueFixedA 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