`.exhaustive()` does not cause TS error when using `instanceOf`
BenLorantfy-AB opened this issue · 1 comments
BenLorantfy-AB commented
Describe the bug
The exhaustive()
function does not raise a TS error when instanceOf
is used and not all possible classes are handled
TypeScript playground with a minimal reproduction case
Example: Playground
In the above example, I would expect that exhaustive()
to raise a NonExhaustiveError
error because ClassB
is not handled
Versions
- TypeScript version: 5.4.5
- ts-pattern version: 4.0.1
gvergnaud commented
This is unfortunately a limitation from the TypeScript type system – structural typing makes it consider two classes with different names as the same type, unless they contain a discriminant property to distinguish them.
class ClassA {}
class ClassB {}
type T = Exclude<ClassA | ClassB, ClassA>
// ^? never
In this case, you could expect T
to be of type ClassB
, but it isn't.
One workaround is to give them a discriminant property:
class ClassA {
type = "ClassA" as const
}
class ClassB {
type = "ClassB" as const
}
let err2: ClassA | ClassB = new ClassB();
const result2 = match(err2)
.with(P.instanceOf(ClassA), (result) => "classA")
.exhaustive(); // ❌