Skip to content

Type inference breaks after the simple assignment operation. #26673

Closed
@dizys

Description

@dizys

TypeScript Version: 3.1.0-dev.20180824

Search Terms: Type Inference, Union Type, Assignment Operation

Code

// Tested by running `tsc` on the command-line
// strictNullChecks: on

interface BarA {
  label: true;
  yoha?(): string;
}

interface BarB {
  label: false;
  yoha?(): void;
}

class Foo {
  bar!: BarA | BarB;

  pia(): void {
    if (this.bar.yoha) {
      this.bar.yoha(); // passed compiling
    }

    if (this.bar.yoha) {
      if (this.bar.label) {
        let label = this.bar.yoha(); // passed
      } else {
        this.bar.yoha(); // passed
      }

      this.bar.yoha(); // passed
    }

    let bar = this.bar;

    if (bar.yoha) {
      bar.yoha(); // passed
    }

    if (bar.yoha) {
      if (bar.label) {
        let label = bar.yoha(); // error while compiling: Object is possibly 'undefined'.
      } else {
        bar.yoha(); // error: Cannot invoke an object which is possibly 'undefined'.
      }

      bar.yoha(); // error: Cannot invoke an object which is possibly 'undefined'.
    }
  }
}

Expected behavior:

bar should behave the same as this.bar since they are indentical and passed by the simplest assignment operation.

Actual behavior:

Type inference for bar seems to break down after being initialized as the indentical of this.bar, shown as the demonstration code.

Playground Link: http://www.typescriptlang.org/play/#src=interface%20BarA%20%7B%0D%0A%20%20label%3A%20true%3B%0D%0A%20%20yoha%3F()%3A%20string%3B%0D%0A%7D%0D%0A%0D%0Ainterface%20BarB%20%7B%0D%0A%20%20label%3A%20false%3B%0D%0A%20%20yoha%3F()%3A%20void%3B%0D%0A%7D%0D%0A%0D%0Aclass%20Foo%20%7B%0D%0A%20%20bar!%3A%20BarA%20%7C%20BarB%3B%0D%0A%0D%0A%20%20pia()%3A%20void%20%7B%0D%0A%20%20%20%20if%20(this.bar.yoha)%20%7B%0D%0A%20%20%20%20%20%20this.bar.yoha()%3B%20%2F%2F%20worked%0D%0A%20%20%20%20%7D%0D%0A%0D%0A%20%20%20%20if%20(this.bar.yoha)%20%7B%0D%0A%20%20%20%20%20%20if%20(this.bar.label)%20%7B%0D%0A%20%20%20%20%20%20%20%20let%20label%20%3D%20this.bar.yoha()%3B%20%2F%2F%20worked%0D%0A%20%20%20%20%20%20%7D%20else%20%7B%0D%0A%20%20%20%20%20%20%20%20this.bar.yoha()%3B%20%2F%2F%20worked%0D%0A%20%20%20%20%20%20%7D%0D%0A%0D%0A%20%20%20%20%20%20this.bar.yoha()%3B%20%2F%2F%20worked%0D%0A%20%20%20%20%7D%0D%0A%0D%0A%20%20%20%20let%20bar%20%3D%20this.bar%3B%0D%0A%0D%0A%20%20%20%20if%20(bar.yoha)%20%7B%0D%0A%20%20%20%20%20%20bar.yoha()%3B%20%2F%2F%20worked%0D%0A%20%20%20%20%7D%0D%0A%0D%0A%20%20%20%20if%20(bar.yoha)%20%7B%0D%0A%20%20%20%20%20%20if%20(bar.label)%20%7B%0D%0A%20%20%20%20%20%20%20%20let%20label%20%3D%20bar.yoha()%3B%20%2F%2F%20failed%0D%0A%20%20%20%20%20%20%7D%20else%20%7B%0D%0A%20%20%20%20%20%20%20%20bar.yoha()%3B%20%2F%2F%20failed%0D%0A%20%20%20%20%20%20%7D%0D%0A%0D%0A%20%20%20%20%20%20bar.yoha()%3B%20%2F%2F%20failed%0D%0A%20%20%20%20%7D%0D%0A%20%20%7D%0D%0A%7D

Related Issues: not yet

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions