This can be seen as the dual of #5156 and an extension of #1447. While the former seeked to limit what could be compared, this issue seeks to be more permissive.
Currently, the following causes an error:
interface I1 {
p1: number
}
interface I2 extends I1 {
p2: number;
}
var x = { p1: 10, p2: 20 };
var y: number | I2 = x;
var z: I1 = x;
// Error: Operator '===' cannot be applied to types 'number | I2' and 'I1'.
if (y === z) {
}
So while y and z are both I2s at runtime, we restrict the two from comparison.
This is especially troublesome with my work on string literal types. In trying to use string literal types on our own codebase, I encountered something like the following:
interface Option {
type: Map<number> | "string" | "boolean" | "number";
}
declare var opt: Option;
// ...
// Error: Operator '!==' cannot be applied to types 'Map<number> | "string" | "boolean" | "number"' and 'string'.
if (opt.type !== "boolean") {
//...
}
switch (opt.type) {
// Error: Type 'string' is not assignable to type 'Map<number> | "string" | "boolean" | "number"'.
case "string":
// ...
}
Of note: because I use the contextual type to inform string literal types, "string" in the case clause remains having the string type.
This can be seen as the dual of #5156 and an extension of #1447. While the former seeked to limit what could be compared, this issue seeks to be more permissive.
Currently, the following causes an error:
So while
yandzare bothI2s at runtime, we restrict the two from comparison.This is especially troublesome with my work on string literal types. In trying to use string literal types on our own codebase, I encountered something like the following:
Of note: because I use the contextual type to inform string literal types,
"string"in thecaseclause remains having thestringtype.