Closed
Description
Bug Report
π Search Terms
recursive nested conditional type guard function
π Version & Regression Information
- This changed between versions 5.1.0-dev.20230303 and 5.1.0-dev.20230304
β― Playground Link
Playground link with relevant code
π» Code
type NestedRecord<K extends string, V> =
K extends `${infer K0}.${infer KR}` ?
{ [P in K0]: NestedRecord<KR, V> } :
{ [P in K]: V };
declare function guardPathX<T>(x: T): x is T & NestedRecord<'a.b.x.c', string>;
declare function guardPathY<T>(x: T): x is T & NestedRecord<'a.b.y.c', string>;
function foo(obj: {}) {
if (guardPathX(obj) && guardPathY(obj)) {
obj.a.b.x.c.toUpperCase(); // okay
obj.a.b.y.c.toUpperCase(); // <-- error, what?
}
}
π Actual behavior
obj
has been narrowed only to {a:{b:{x:{c: string}}}}
.
π Expected behavior
obj
should be narrowed to {a:{b:{x:{c: string}}}} & {a:{b:{y:{c: string}}}}
.
This is a weird one. Seems to be caused by the recursive NestedRecord
utility type (if I replace that with hardcoded types it works) interacting with multiple type guard applications. Probably hitting some limit somewhere where it gives up? Or an inaccurate variance shortcut? Not sure. Anyway this broke some Stack Overflow answer I was working on and it would be nice to know what's up with it.