From type:
type BeforeType = "1" | "2"
I would like to get a type:
type AfterType = 1 | 2
From type:
type BeforeType = "1" | "2"
I would like to get a type:
type AfterType = 1 | 2
TypeScript does not currently have support for a type function (let's call it StringToNumber<T>) that converts string literal types representing numbers into their corresponding numeric literals. I don't know if there are any open issues in GitHub asking specifically for this, but microsoft/TypeScript#26382 requests the ability to do perform operations on numeric literals, which is fairly close (at least if you could do that you could probably write a decent StringToNumber<T> yourself).
There are various possible workarounds, but either they only work for hardcoded lists of numbers, or at best you can use tuple type manipulation to represent non-negative whole numbers. It is certainly not worth doing any of these things if you're looking at numbers like "1" and "2" though; any user-written implementation of StringToNumber<T> is going to be more complicated or fragile than just writing 1 and 2 yourself.
For example, here's a reasonably straightforward implementation of using recursive conditional types to calculate StringToNumber<T> using tuples:
type StringToNumber<T extends `${number}`, R extends number[] = []> =
T extends keyof R ? R[T] : StringToNumber<T, [...R, R['length']]>
And it totally works for "1" | "2" without a problem:
type NewAfterType = StringToNumber<"1" | "2">
// type NewAfterType = 1 | 2
But for TS4.4, it bails out for numbers bigger than ~40:
type Oops = StringToNumber<"100"> // error TS4.4
// Type instantiation is excessively deep and possibly infinite
And bad things happen with negative or non-whole numbers:
type Blah = StringToNumber<"-2"> // error
// Type instantiation is excessively deep and possibly infinite
type AlsoBlah = StringToNumber<"0.5"> // error
// Type instantiation is excessively deep and possibly infinite
I don't think it's worth it unless your use case is specifically dealing with small nonnegative whole numbers, and for those you can just write a lookup table:
type Nums = [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47, 48, 49
];
type StringToNumber<T extends Exclude<keyof Nums, keyof any[]>> = Nums[T]
So StringToNumber<T> is not provided and not easily achievable.
That being said, TypeScript does have the ability to do the reverse (let's call it NumberToString<T>) where you convert numeric literal types to their corresponding string literal types. The implementation uses template literal types:
type NumberToString<T extends number> = `${T}`;
So you can generate BeforeType from AfterType instead:
type NewBeforeType = NumberToString<AfterType>;
// type NewBeforeType = "1" | "2"
Depending on the use case, you might be able to refactor to start with numbers and end up with strings. Or you could possibly write out both BeforeType and AfterType manually, and have the compiler check that AfterType corresponds to BeforeType by comparing BeforeType to NumberToString<AfterType>. For example:
declare var checkConversion: BeforeType;
declare var checkConversion: NewBeforeType;
// -------> ~~~~~~~~~~~~~~~
// if there's an error here, it means you made a mistake