Repository navigation
Support inferred string-modified union types #17512
Copy link
Copy link
Closed
Labels
Domain: Literal TypesUnit types including string literal types, numeric literal types, Boolean literals, null, undefinedUnit types including string literal types, numeric literal types, Boolean literals, null, undefinedSuggestionAn idea for TypeScriptAn idea for TypeScriptToo ComplexAn issue which adding support for may be too complex for the value it addsAn issue which adding support for may be too complex for the value it adds
Description
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?
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
Domain: Literal TypesUnit types including string literal types, numeric literal types, Boolean literals, null, undefinedUnit types including string literal types, numeric literal types, Boolean literals, null, undefinedSuggestionAn idea for TypeScriptAn idea for TypeScriptToo ComplexAn issue which adding support for may be too complex for the value it addsAn issue which adding support for may be too complex for the value it adds
Activity
aluanhaddad commentedon Jul 30, 2017
I believe this is roughly the same idea as proposed in #16746 (comment)
I think it is a great idea, but might be highly complex.
I would say it is not an edge case because, if generalized somewhat, it could allow for something like (syntax is just something I made up)
gcnew commentedon Jul 30, 2017
Another related issue #12940.
DanielRosenwasser commentedon Aug 2, 2017
As well as #12754
RyanCavanaugh commentedon Oct 10, 2017
We'd either have to invent a completely new kind of type (a deferred-expansion union), which would be a ton of work, or risk people accidently creating combinatorially explosive literal types. This doesn't seem to come up often enough to warrant either scenario.