Skip to content

Support inferred string-modified union types #17512

Closed
@RonPenton

Description

@RonPenton

I ran into an interesting situation that I wanted to run by the community to see if there's a way to add a new feature into TypeScript to support. I'll grant that it's an edge-case, but it seems like something that could be kind of neat.

Here's the code:

Code

// From Library 1
type status = "success" | "error" | "warning" | "info";

// From Library 2
type statusColor = "success" | "success-dark" | "error" | "error-dark" | "warning" | "warning-dark" | "info" | "info-dark";

// My library
function getColorFromStatus(status: status): statusColor {

    // ideal case: doesn't work:
    return status + "-dark";    // Error TS2322	Type 'string' is not assignable to type 'statusColor'

    // compromise: compiles but not type-safe. Changes to "status" type won't be caught.
    return status + "-dark" as statusColor;

    // safe case: works but extra code + runtime penalty:
    switch (status) {
        case "success": return "success-dark";
        case "error": return "error-dark";
        case "warning": return "warning-dark";
        case "info": return "info-dark";
    }
}

I think it would be neat if the expression:

status + "-dark"

could be automatically inferred to be of type:

"success-dark" | "error-dark" | "warning-dark" | "info-dark";

It's probably a lot more complex than it seems. And there's probably a heck of a lot of issues dealing with what happens with other string operations or if a runtime function like .toUpperCase() is called on the string, and what happens if any item in the union isn't a string, etc, etc. But still.

Any thoughts?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Domain: Literal TypesUnit types including string literal types, numeric literal types, Boolean literals, null, undefinedSuggestionAn idea for TypeScriptToo ComplexAn issue which adding support for may be too complex for the value it adds

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions