Here is code:
type T = 'a' | "b"
type M = {
a: 1,
b: 2
}
function a(a: 'a') {}
function m1(a: 1) {}
function f<TT extends T>(t: TT, p: M[TT]) {
switch (t) {
case "a": {
a(t)
m1(p) // Argument of type '1 | 2' is not assignable to parameter of type '1'
break
}
}
}
Why p
wasn't narrowed to 1
? Are there a neat workaround without type casts?
TypeScript is unable to recognize that p
corrolates with t
as explained in microsoft/TypeScript#35873. You'll need another type guard to narrow p
. The most straightforward syntax is to use switch (true)
narrowing which was recently added in TypeScript 5.3.
type T = "a" | "b";
type M = {
a: 1;
b: 2;
};
declare function a(a: "a"): void;
declare function m1(a: 1): void
function f<TT extends T>(t: TT, p: M[TT]) {
switch (true) {
case t === "a" && p === 1:
a(t);
m1(p);
break;
}
}