Bug Report
π Search Terms
generic predicate custom type guard
π Version & Regression Information
Occurs in versions 4.2, 4.3 and nightly
In version 4.1 the custom type guard isNumClass didn't work at all inside ComplexStore.get
β― Playground Link (full example)
Playground link with full code
π» Code (partial)
Small code sample (please see the playground link for full example).
// This is only a chunk of the problem case, please see the playground link for full code
const isNumClass = <Item extends NumClass<number> | StrClass<string>> (
item: Item
): item is Extract<Item, NumClass<any>> => {
return (item instanceof NumClass);
}
/**
* 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
}
// 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
return item; // type is never
}
}
π Actual behavior
- The type predicate modifies the type outside its scope. This happens only in a more complex scenario when using generics in a class with a 2-dimensional dictionary. The problem does not occur in the same class with a one-dimensional dictionary.
π Expected behavior
- The narrowed type should not leak outside the scope. It should remain unchanged.
I'm sorry if it's not a bug, but I think there are high chances it is. The one-dimensional example works ok now, and worked on in the previous version. The 2-dimensional example didn't work at all prior 4.2 and now works, but there are issues with it
By the way, I'm aware I could use bare instance of, it appeared to work in this simplified example, but it didn't work in my real case (although I will continue to experiment with it).
Bug Report
π Search Terms
generic predicate custom type guard
π Version & Regression Information
Occurs in versions 4.2, 4.3 and nightly
In version 4.1 the custom type guard
isNumClassdidn't work at all insideComplexStore.getβ― Playground Link (full example)
Playground link with full code
π» Code (partial)
Small code sample (please see the playground link for full example).
π Actual behavior
π Expected behavior
I'm sorry if it's not a bug, but I think there are high chances it is. The one-dimensional example works ok now, and worked on in the previous version. The 2-dimensional example didn't work at all prior 4.2 and now works, but there are issues with it
By the way, I'm aware I could use bare
instance of, it appeared to work in this simplified example, but it didn't work in my real case (although I will continue to experiment with it).