Skip to content

To/from assignability is too strict of a check for comparison and other operations #5300

@DanielRosenwasser

Description

@DanielRosenwasser

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FixedA PR has been merged for this issueSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions