Description
Bug Report
π Search Terms
dependant parameters
discriminated union parameters
π Version & Regression Information
TypeScript 4.6.x -> TypeScript 4.9.3 & Nightly
- This is the behavior in every version I tried, and I reviewed the FAQ
β― Playground Link
Playground link with relevant code
π» Code
The release notes for 4.6 explain how control flow analysis for dependant parameters can work for functions whose arguments are defined as tuples:
type Func = (...args: ["a", number] | ["b", string]) => void;
const f1: Func = (kind, payload) => {
if (kind === "a") {
payload.toFixed(); // 'payload' narrowed to 'number'
}
if (kind === "b") {
payload.toUpperCase(); // 'payload' narrowed to 'string'
}
};
f1("a", 42);
f1("b", "hello");
However, as soon as you use a more complex type, the code no longer compiles:
type A = { kind: "a"; }
type B = { kind: "b"; }
type Func = (...args: [A, number] | [B, string]) => void;
const f1: Func = ({ kind }, payload) => {
if (kind === "a") {
payload.toFixed(); // 'payload' should be narrowed to 'number'
}
if (kind === "b") {
payload.toUpperCase(); // 'payload' should be narrowed to 'string'
}
};
f1({ kind: "a" }, 42);
f1({ kind: "b" }, "hello");
π Actual behavior
On the line with payload.toFixed()
, TypeScript gives the following compiler error:
Property 'toFixed' does not exist on type 'string | number'.
Property 'toFixed' does not exist on type 'string'.
On the line with payload.toUpperCase()
, TypeScript gives the following compiler error:
Property 'toUpperCase' does not exist on type 'string | number'.
Property 'toUpperCase' does not exist on type 'number'.(2339)
π Expected behavior
I would expect TypeScript to apply the same control flow analysis for the more complex typed parameters as the simple ones. I'm actually trying to use this feature while playing around with the new decorators that @rbuckton has been working on. I want to make a property decorator work with both accessors and setters, taking advantage of control flow analysis to return the appropriate value without casting.