* Track source and target relationship stack depth seperately, only increase on change in value * Add baselines for test from #43485 * Bail on unwrapping conditional constraints on the source side when the source conditional is already known to be spooling out of control * More usage of isDeeplyNestedType to block _specifically_ conditional recursion on only one side * Negative cases of getNarrowedType that match the exact type should be filtered out, even when generic * Add test and fix for #44404 * Swap to manually specifying left and right recursion * Rename Left -> Source, Right -> Target Co-authored-by: Andrew Branch <andrew@wheream.io>
45 lines
1.6 KiB
Plaintext
45 lines
1.6 KiB
Plaintext
=== tests/cases/compiler/genericCapturingFunctionNarrowing.ts ===
|
|
function needsToNarrowTheType<First extends { foo: string }, Second extends { bar: string }, SubFirst extends First, SubFirstMore extends First & {other: string}>(thing: First | SubFirst | SubFirstMore | Second) {
|
|
>needsToNarrowTheType : <First extends { foo: string; }, Second extends { bar: string; }, SubFirst extends First, SubFirstMore extends First & { other: string; }>(thing: First | SubFirst | SubFirstMore | Second) => void
|
|
>foo : string
|
|
>bar : string
|
|
>other : string
|
|
>thing : First | Second | SubFirst | SubFirstMore
|
|
|
|
if (hasAFoo(thing)) {
|
|
>hasAFoo(thing) : boolean
|
|
>hasAFoo : (value: First | Second) => value is First
|
|
>thing : First | Second | SubFirst | SubFirstMore
|
|
|
|
console.log(thing.foo);
|
|
>console.log(thing.foo) : void
|
|
>console.log : (...data: any[]) => void
|
|
>console : Console
|
|
>log : (...data: any[]) => void
|
|
>thing.foo : string
|
|
>thing : First | SubFirst | SubFirstMore
|
|
>foo : string
|
|
}
|
|
else {
|
|
// I would expect this to work because the type should be narrowed in this branch to `Second`
|
|
console.log(thing.bar); // Error: Property 'bar' does not exist on type 'First | Second'.
|
|
>console.log(thing.bar) : void
|
|
>console.log : (...data: any[]) => void
|
|
>console : Console
|
|
>log : (...data: any[]) => void
|
|
>thing.bar : string
|
|
>thing : Second
|
|
>bar : string
|
|
}
|
|
|
|
function hasAFoo(value: First | Second): value is First {
|
|
>hasAFoo : (value: First | Second) => value is First
|
|
>value : First | Second
|
|
|
|
return "foo" in value;
|
|
>"foo" in value : boolean
|
|
>"foo" : "foo"
|
|
>value : First | Second
|
|
}
|
|
}
|