Skip to content

this[variable] and this[stringLiteral] have different behavior #29042

Closed
@afrieder

Description

TypeScript Version: 3.3.0-dev.201xxxxx, --strictNullChecks, no other strict flags

Search Terms:
string literal types property access

Code

class X {
    x: number | undefined;

    constructor() {
        this.x = 5;
        // Type checks, this.x is `number`
        this.x.toString();
        // Type checks, this['x'] is `number`
        this['x'].toString();
        // Types `this[thing]` as `number | undefined`
        // and throws an error as "Object is possibly undefined"
        const thing: 'x' = 'x';
        this[thing].toString();
    }
}

Expected behavior:
this['x'] and const thing: 'x' = 'x'; this[thing] should resolve to the same thing.

Actual behavior:
const thing: 'x' = 'x'; this[thing] resolves to the base property type (number | undefined) without having the context that it's been assigned in the same block

Disclaimer: if you also use --strictPropertyInitialization Typescript does the correct thing and permits all three.

Playground Link:
http://www.typescriptlang.org/play/#src=class%20X%20%7B%0A%20%20%20%20x%3A%20number%20%7C%20undefined%3B%0A%0A%20%20%20%20constructor()%20%7B%0A%20%20%20%20%20%20%20%20this.x%20%3D%205%3B%0A%20%20%20%20%20%20%20%20%2F%2F%20Type%20checks%2C%20x%20is%20%60number%60%0A%20%20%20%20%20%20%20%20this.x.toString()%3B%0A%20%20%20%20%20%20%20%20%2F%2F%20Type%20checks%2C%20x%20is%20%60number%60%0A%20%20%20%20%20%20%20%20this%5B'x'%5D.toString()%3B%0A%20%20%20%20%20%20%20%20let%20thing%3A%20'x'%20%3D%20'x'%3B%0A%20%20%20%20%20%20%20%20%2F%2F%20Types%20%60this%5Bthing%5D%60%20as%20%60number%20%7C%20undefined%60%0A%20%20%20%20%20%20%20%20%2F%2F%20and%20throws%20an%20error%20as%20%22Object%20is%20possibly%20undefined%22%0A%20%20%20%20%20%20%20%20this%5Bthing%5D.toString()%3B%0A%20%20%20%20%7D%0A%7D%0A

Related Issues:

Activity

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

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScriptDomain: Control FlowThe issue relates to control flow analysis

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions