Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to tell TypeScript my function argument is an Enum key?

I have an enum thats maps HTTP status to their code, as follow:

enter image description here

I can easily get those codes by accessing their keys (notice how IntelliSense shows HttpStatus.NOT_FOUND = 404 on the right panel)

enter image description here

Now let's say I have a function called sendStatus:

How should I type this function in order to get those codes autocompleted by IntelliSense?

enter image description here

Using keyof typeof doesn't work because it doesn't autocomplete the enum values.

like image 201
BernaMariano Avatar asked Apr 14 '20 22:04

BernaMariano


People also ask

Can enum be a type in TypeScript?

There are three types of TypeScript enums, namely: Numeric enums. String enums. Heterogeneous enums.

What is an enum in TypeScript?

In TypeScript, enums, or enumerated types, are data structures of constant length that hold a set of constant values. Each of these constant values is known as a member of the enum. Enums are useful when setting properties or values that can only be a certain number of possible values.

Is not assignable to parameter of type enum?

The error "Type string is not assignable to type Enum" occurs when we try to use a string literal in the place of an enum value. To solve the error, use dot or bracket notation to access the specific enum property or use a type assertion.


1 Answers

What you want is not directly possible. When you do keyof typeof you create a union type 'CREATED' | 'OK' | 'NOT_FOUND' ... that is completely separate from the enum it once was.

The closest you can get is by doing

function sendStatus(code: HttpStatus) {
    // code
}

send(HttpStatus.OK) // This will autocomplete and show the status code numbers

and then converting the code to string inside the sendStatus function.

It's hard to say what you really want without knowing the exact usage you're looking for, but I would consider just having a plain old object instead of the enum

const HTTP_STATUS = {'OK':200, 'CREATED':201} as const

Then, if you need to, you can also create both of the types like so

type StringStatus = keyof typeof HTTP_STATUS // 'OK' | 'CREATED'
type NumsStatus = (typeof HTTP_STATUS)[keyof typeof HTTP_STATUS] // 200 | 201

Generally there's rarely a good reason to use enums in modern TS. Usually objects and/or union types do the job much better.

like image 147
SquattingSlavInTracksuit Avatar answered Sep 23 '22 13:09

SquattingSlavInTracksuit