Home > Back-end >  How to constrain a variable to be one of the types in an enum
How to constrain a variable to be one of the types in an enum

Time:07-25

How can implement a generic type which constraints the value of the variable to be any of the types in the enum?

enum SexTypes {
    Male,
    Female
}

This would be the type to implement:

type TApplyEnumConstraint<T> ........

To achieve this:

let sex: TApplyEnumConstraint<SexTypes> = "Male"  // ==> OK
let sex: TApplyEnumConstraint<SexTypes> = "Female"  // ==> OK
let sex: TApplyEnumConstraint<SexTypes> = "foo"  // ==> Error

CodePudding user response:

As mentioned in the comments a union type would probably fit better:

type SexTypes = "Male" | "Female";

If you want to stick to your enum approach what you can do is convert your enum to a union type using string literals. That way you would get the same result as above but still have your enum for whatever reason. However you would have to define enum values first for this.

enum SexTypes {
  Male = "Male",
  Female = "Female"
}

const sex1: `${SexTypes}` = "Female";
const sex2: `${SexTypes}` = "Male";
const sex3: `${SexTypes}` = "foo";
//    ~~~~ -> Type '"foo"' is not assignable to type '"Male" | "Female"'.

If you want to keep the generic it get's a little more complicated:

enum SexTypes {
  Male = "Male",
  Female = "Female"
}

type TApplyEnumConstraint<T> = T extends string
  ? string extends T
    ? never
    : `${T}`
  : never;

const sex4: TApplyEnumConstraint<SexTypes> = "Female";
const sex5: TApplyEnumConstraint<SexTypes> = "Male";
const sex6: TApplyEnumConstraint<SexTypes> = "foo";
//    ~~~~ -> Type '"foo"' is not assignable to type '"Male" | "Female"'.

Note: You can also replace the string literals with keyof typeof SexTypes. You will get the same union type result. (="Male" | "Female")

const sex: keyof typeof SexTypes = "Female";
  • Related