Review the program below.
interface Eq<A> {
eq(this: A, that: A): boolean;
};
class Pair<A> implements Eq<Pair<A>> {
constructor(public x: A, public y: A) {}
eq(this: Pair<A>, that: Pair<A>): boolean {
return this.x === that.x && this.y === that.y;
}
}
class Triple<A> implements Eq<Triple<A>> {
constructor(public x: A, public y: A, public z: A) {}
eq(this: Triple<A>, that: Triple<A>): boolean {
return this.x === that.x && this.y === that.y && this.z === that.z;
}
}
const eq = <A extends Eq<A>>(x: A, y: A): boolean => x.eq(y);
console.log(eq(new Pair(1, 2), new Triple(1, 2, 3)));
console.log(eq(new Triple(1, 2, 3), new Pair(1, 2)));
I find it surprising that there are no type errors thrown by the TypeScript compiler in the last two lines of code. In theory, applying the eq
function to different types should result in an error. The actual output from the program is a mix of true
and false
.
What might be causing the TypeScript compiler to overlook these type errors in the given program? Is there a way to configure it to detect and flag such discrepancies?