Home > Blockchain >  How can I use type key as enum?
How can I use type key as enum?

Time:12-11

eg I have

type typeA = "A1" | "A2" | "A3";

then I want to use type value direction

typeA.A1; // "A1"

Is it possible?

CodePudding user response:

As I said in my comment, you can't use a type alias as an enum because of type erasure. typeA will not exist in the generated Javascript and thus not at runtime.[1]

Since you said in your comment that typeA "is maintained by 3rd party", there is nothing you can do. But also there is nothing you need to do:

  • Why would you write typeA.A1 in your code when you could write "A1"? It's almost like defining const TWO = 2 in your code and using TWO instead of the literal 2.
  • There is no additional type safety by using typeA.A instead of "A1". Static type checking will prevent you from assigning/passing any values other that those allowed by typeA to any variables or parameters with that type.
  • Any IDE that supports Typescript will auto suggest legal values for such variables and parameters.

but let's say you really needed/wanted to be able to say typeA.A1...

The code will have to work the other way around: define Enum values (not necessarily using the enum syntax), and then define a type alias that represents the union of those values.

For example:

enum A {A1 = "A1", A2 = "A2", A3 = "A3" }

// type typeA = "A1" | "A2" | "A3"
type typeA = keyof typeof A

Usage:

function checkA(arg: typeA):void {
    console.log(arg)
}

checkA(A.A1)  //ok
checkA("A1")  //ok
checkA("A4")  //error

let v1: A = A.A1
let v2: typeA = "A1"
let v3: string = "A1"

checkA(v1)    //ok
checkA(v2)    //ok
checkA(v3)    //error

You could instead define the function arg as arg: A, but it would be even more strict, only accepting references to the A enum, not the string "A1" or the variable v2:

function checkA(arg: A):void {
    console.log(arg)
}

You would have to convince the third party to make this change.


[1] There is a nice table in the Typescript docs that summarize which things exist after transpiling to Javascript.

CodePudding user response:

I don't think there is a way to convert an string to an enum. However what you can do is define your own enum.

Then create a helper function that will give you a typescript error if the enum is ever out of sync with the original string.

This is a bit hacky but it should suffice for an external string union that you don't control.

The way to do that is to first define the enum as such:

type ThirdPartyString =  "A1" | "A2" | "A3";

enum YourEnum {
  A1 = "A1",
  A2 = "A2",
  A3 = "A3"
};

Then you can create a helper function like so:

type CheckIfEnumIsSameAsString = `${YourEnum}` extends ThirdPartyString
  ? ThirdPartyString extends `${YourEnum}`
    ? YourEnum
    : never
  : never;

const test = (arg: CheckIfEnumIsSameAsString) => {};

// pass this any value from YourEnum
test(YourEnum.A1);

That helper function will give an error if the Enum is ever different to the external string.

Playground

  • Related