Skip to content

Control flow analysis for dependent parameters doesn't work for methodsΒ #48160

Closed
@jcalz

Description

@jcalz

Bug Report

πŸ”Ž Search Terms

control flow analysis, dependent parameters, methods, #47190, #48110

πŸ•— Version & Regression Information

This behavior has been present since #47190 was merged, so TS4.6.

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

interface Foo {
  method(...args: ['a', number] | ['b', string]): void
};

const methodSyntax: Foo = {
  method(kind, payload) {
    if (kind === 'a') {
      payload.toFixed(); // error, Property 'toFixed' does not exist on type 'string | number'
    }
    if (kind === 'b') {
      payload.toUpperCase(); // error, Property 'toUpperCase' does not exist on type 'string | number'
    }
  }
}

πŸ™ Actual behavior

Checking kind inside the body of method() does not narrow payload from string | number.

πŸ™‚ Expected behavior

Given #47190, I'd expect kind === 'a' to narrow payload to number, and kind === 'b' to narrow payload to string, which does happen when method is a function expression:

const funcExpr: Foo = {
  method: function (kind, payload) {
    if (kind === 'a') {
      payload.toFixed()  // okay
    }
    if (kind === 'b') {
      payload.toUpperCase(); // okay
    }
  }
}

And when method is an arrow function:

const arrowFunc: Foo = {
  method: (kind, payload) => {
    if (kind === 'a') {
      payload.toFixed(); // okay
    }
    if (kind === 'b') {
      payload.toUpperCase(); // okay
    }
  }
}

And by #46266 when destructured from a rest argument:

const manualDestructuring: Foo = {
  method(...args) {
    const [kind, payload] = args;
    if (kind === 'a') {
      payload.toFixed(); // okay
    }
    if (kind === 'b') {
      payload.toUpperCase(); // okay
    }
  }
} 

I don't know whether this is really a bug or just a follow-up feature request to add to #46658 / #47190. For context: I mentioned this in #47190, and @Andarist has written a PR for it at #48110.

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScript

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions