2

Is it possible to convert enum that looks for exmp:

enum StatusCodeEnum {
  OK = 200,
  BAD_REQUEST = 400,
  UNAUTHORIZED = 401,
  FORBIDDEN = 403,
  NOT_FOUND = 404,
  INTERNAL_SERVER_ERROR = 500,
  SERVICE_UNAVAILABLE = 503,
}

to template type that will have only numbers like

TypeFromEnum = 200 | 400 | 500 | ...  ---> numbers

i only interested in enum transformation without switching to plain Object with "as const"

4
  • It does become a lot easier with the as const trick. With const statusCodes = { OK: 200, … } as const, type StatusCode = keyof typeof statusCodes gives you the enum as a union type and then you can do type TypeFromEnum = (typeof statusCodes)[StatusCode]. Any particular reason why you want to avoid this? Commented Apr 11, 2022 at 13:09
  • "planeObject" is... what? ✈ Do you mean a "plain object"? Commented Apr 11, 2022 at 13:14
  • Enums are intended for use cases when the particular values are not meant to be used directly; if you want 200 you should always and only be using StatusCodeEnum.OK. If you really need a bare 200 then enums are not the right solution for your use case. Anyway, for the question as asked... right now there's no plausible way to do what you want programmatically, although if ms/TS#48094 is merged there will be. Commented Apr 11, 2022 at 13:18
  • I guess you could do this, but it forces the compiler to do a lot of processing to calculate a big union of numbers only to throw away most of them. So it bogs down performance and is fragile; if you changed any of the StatusCodeEnum values to a negative number or a non-integer or a very big number you'd miss things. It's easier and better to just write the type out manually. Commented Apr 11, 2022 at 13:26

3 Answers 3

4

This will be possible in TypeScript 4.8, with more specific inference from template string types.

The approach looks like this:

type TypeFromEnum = `${Extract<StatusCodeEnum, number>}` extends 
  `${infer N extends number}` ? N : never;
// type TypeFromEnum = 200 | 400 | 401 | 403 | 404 | 500 | 503

You can't easily iterate through a purely numeric enum because it's not internally represented as a union type, so the method above first makes sure it grabs only numeric enum members (in case it's a mixed string/numeric enum), converts them to a union of string literal types, and then converts back into numeric literal types via the infer N extends nmber technique.

Playground link to code

Sign up to request clarification or add additional context in comments.

Comments

1

try this:

type StatusCodeType = `${StatusCodeEnum}`

// return -> `200 | 400 | 401 | ... `

1 Comment

This results in "200" | "400" | ..., which are strings, not numbers.
0

//can use this if you only want specific enum values

type typeFromEnum = StatusCodeEnum.OK | StatusCodeEnum.BAD_REQUEST | StatusCodeEnum.INTERNAL_SERVER_ERROR

// Or this if you want the type to be able to be any of the enum but you might as well just use the enum as the type.
type typeFromEnum = StatusCodeEnum;

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.