Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jcalz opened this issue Mar 7, 2022 · 1 comment Β· Fixed by #48110
Closed

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

jcalz opened this issue Mar 7, 2022 · 1 comment Β· Fixed by #48110
Labels
Bug A bug in TypeScript
Milestone

Comments

@jcalz
Copy link
Contributor

jcalz commented Mar 7, 2022

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.

@RyanCavanaugh RyanCavanaugh added the Bug A bug in TypeScript label Mar 8, 2022
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Mar 8, 2022
@RyanCavanaugh
Copy link
Member

Seems like an oversight

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants