Closed
Description
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.