Patrick Da Silva
Patrick Da Silva

Reputation: 1954

Having a type for options encoded as strings in Typescript

I don't know exactly what I'm looking for, so I apologize if the title is too generic.

There's a pattern I developed when I was coding in JavaScript where when a variable could only take one of n possible values, I would define an object like this:

const REQUEST_STATUS = {
  PENDING: "pending",
  SUCCESS: "success",
  FAILED: "failed"
}

and then later in the code I would avoid hardcoding one of those values by writing

const requestStatus = REQUEST_STATUS.PENDING

This has the advantage that in my IDE, if I hover over REQUEST_STATUS.PENDING, I actually see the object and the other possible values of the option.

I recently started working on a Typescript codebase where they are using union types:

type RequestStatus = "pending" | "success" | "failed"

and this has the disadvantage that a lot of times, logic is performed on variables that are not type-annotated (yeah, yay me) and my IDE labels the types as any, so I really have nowhere to start. I want to avoid hardcoding strings when performing logic with variables with such type. Is there any nice way to preserve the advantages of my vanilla JavaScript technique within Typescript in a 'Typescripty' way? Basically I need two features:

Upvotes: 1

Views: 775

Answers (2)

Patrick Da Silva
Patrick Da Silva

Reputation: 1954

I settled for using string enums in this way:

/**
 * @enum REQUEST_STATUS
 * @property pending - Status used when the API call is on going
 * @property success - Status used when the API call is settled successfully
 * @property failed - Status used when the API call is settled unsuccessfully
 */
enum REQUEST_STATUS {
  PENDING = "pending",
  SUCCESS = "success",
  FAILED = "failed"
}

Since enums are a type in themselves, there was no actual need for me to convert the enum into a union type; enums do that well already when it comes to logic. All I was interested in was being able to hover over my enum when being used in some other scripts to see what values it can take. The JSDoc is something I wanted to use anyway, and this way I can document the values as well. So this sounds like the way to go for me.

Upvotes: 1

Andrew Nic
Andrew Nic

Reputation: 168

what about doing like this:

enum REQUEST_STATUS {
  PENDING = "pending",
  SUCCESS = "success",
  FAILED = "failed"
}

type RequestStatus = REQUEST_STATUS.PENDING | REQUEST_STATUS.SUCCESS |REQUEST_STATUS.FAILED, 

but i think doing type RequestStatus = REQUEST_STATUS , if you need all.

Upvotes: 1

Related Questions