612c92d603
* 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>
110 lines
3.8 KiB
Plaintext
110 lines
3.8 KiB
Plaintext
tests/cases/compiler/quickinfoTypeAtReturnPositionsInaccurate.ts(33,15): error TS2339: Property 'numExclusive' does not exist on type 'NumClass<number> | StrClass<string>'.
|
|
Property 'numExclusive' does not exist on type 'StrClass<string>'.
|
|
|
|
|
|
==== tests/cases/compiler/quickinfoTypeAtReturnPositionsInaccurate.ts (1 errors) ====
|
|
class NumClass<T extends number> {
|
|
private value!: T;
|
|
public get(): T {
|
|
return this.value;
|
|
}
|
|
public numExclusive() { }
|
|
}
|
|
|
|
class StrClass<T extends string> {
|
|
private value!: T;
|
|
public get(): T {
|
|
return this.value;
|
|
}
|
|
public strExclusive() { }
|
|
}
|
|
|
|
const isNumClass = <Item extends NumClass<number> | StrClass<string>> (
|
|
item: Item
|
|
): item is Extract<Item, NumClass<any>> => {
|
|
return (item instanceof NumClass);
|
|
}
|
|
|
|
/**
|
|
* An example with one dimensional dictionary. Everything worked ok here, even in prior
|
|
* versions.
|
|
*/
|
|
class SimpleStore<Entries extends { [index: string]: NumClass<number> | StrClass<string> }> {
|
|
private entries = { } as Entries;
|
|
|
|
public get<EntryId extends keyof Entries>(entryId: EntryId): Entries[EntryId] {
|
|
let entry = this.entries[entryId];
|
|
|
|
entry.numExclusive(); // error - expected.
|
|
~~~~~~~~~~~~
|
|
!!! error TS2339: Property 'numExclusive' does not exist on type 'NumClass<number> | StrClass<string>'.
|
|
!!! error TS2339: Property 'numExclusive' does not exist on type 'StrClass<string>'.
|
|
|
|
if (isNumClass(entry)) {
|
|
entry.numExclusive(); // works
|
|
return entry;
|
|
}
|
|
|
|
return entry; // type is Entries[EntryId] - all fine
|
|
}
|
|
}
|
|
|
|
type Slice = {
|
|
[index: string]: NumClass<number> | StrClass<string>
|
|
}
|
|
|
|
/**
|
|
* A an example with 2-dimensional dictionary.
|
|
*
|
|
* In v4.1 the `isNumClass` type guard doesn't work at all.
|
|
* In v4.2 or later, `isNumClass` type guard leaks outside its
|
|
* scope.
|
|
*/
|
|
class ComplexStore<Slices extends { [index: string]: Slice }> {
|
|
private slices = { } as Slices;
|
|
|
|
public get<SliceId extends keyof Slices, SliceKey extends keyof Slices[SliceId]>(
|
|
sliceId: SliceId, sliceKey: SliceKey
|
|
): Slices[SliceId][SliceKey] {
|
|
let item = this.slices[sliceId][sliceKey];
|
|
|
|
if (isNumClass(item)) {
|
|
item.numExclusive(); // works only since version 4.2
|
|
}
|
|
|
|
item.get();
|
|
|
|
// unfortunately, doesn't work completely.
|
|
// it seems like item's predicated type leaks outside the bracket...
|
|
|
|
return item; // type is Extract ...
|
|
}
|
|
|
|
public get2<SliceId extends keyof Slices, SliceKey extends keyof Slices[SliceId]>(
|
|
sliceId: SliceId, sliceKey: SliceKey
|
|
): Slices[SliceId][SliceKey] {
|
|
let item = this.slices[sliceId][sliceKey];
|
|
|
|
if (isNumClass(item)) {
|
|
return item;
|
|
}
|
|
// it seems like the compiler asumes the above condition is always
|
|
// truthy
|
|
|
|
item.get();
|
|
|
|
return item; // type is never
|
|
}
|
|
}
|
|
|
|
// from the compiler itself
|
|
interface BuilderProgram {
|
|
getProgram(): Program;
|
|
}
|
|
interface Program {
|
|
state: any;
|
|
}
|
|
declare function isBuilderProgram<T extends BuilderProgram>(program: Program | T): program is T;
|
|
export function listFiles<T extends BuilderProgram>(program: Program | T) {
|
|
const x: Program = isBuilderProgram(program) ? program.getProgram() : program;
|
|
} |