9

Is it possible to convert string union type to number union type in TypeScript?

e.g. Given a union type A:

type A = '7' | '8' | '9'

Convert to:

type B = 7 | 8 | 9

The numbers in A can be any number, not just digits or integers.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
loveyunk
  • 358
  • 3
  • 11

2 Answers2

4

This is now possible (as of typescript 4.8.4), using type inference:

type ToNumber<S> = S extends `${infer N extends number}` ? N : never

type A = "7" | "8" | "9" | "0.11" | "1.52"

type B = ToNumber<A>

This unfortunately cannot handle any other number formats, even in 5.2.0-beta (so 1.2e3, 0xff4, 0b1110 are off the table).

Playground Here

Mr Helpful
  • 53
  • 1
  • 8
  • 1
    Can we summarize what is happening like so? 1. Create a new type `N` using `infer`. `N` is a number. 2. Wrap that up as a string and see if `S` is compatible (`extends`) with this. In other words, is `S` a 'number-like string?' 3. If it is, return this number, therein converting `S` to a number. Probably 1) and 2) are somewhat interchangeable in terms of the order that this is read in. – CodeFinity Aug 14 '23 at 20:19
  • 1
    That seems roughly right, but the conditional `S extends ...` limits the types returned for `N` to only those that can be 'stringified' to `S` – Mr Helpful Aug 21 '23 at 16:30
1

Going from string to number is not possible, as far as I know. However, how about the other way around, would that work for you? You can do this by using template literals:

type B = 7 | 8 | 9;

type A = `${B}`; 

Playground Link

Poul Kruijt
  • 69,713
  • 12
  • 145
  • 149