'Check if string is member of Union type

To avoid type casting, I would like to learn when it's possible to safely determine the type of given values. I can do this with string enums like this:

enum Category {
    circle = "circle",
    square = "square",
}

const isObjValue = (val: any, obj: any) => Object.values(obj).includes(val)

isObjValue('circle', Category) // true

But how would I do it with string Unions?

const Category = "circle" | "square"

const isValidCategory = (string) => {
  if (/* string is in Category */) {
    return string as Category
  }
}

Still learning TS!



Solution 1:[1]

To avoid having to remember to always update both the type and "is" check function, you can instead use an array and have TS convert it to a union:

const ALL_CATEGORIES = ["circle", "square"] as const;
type typedCategoryList = typeof ALL_CATEGORIES;
type Category = typedCategoryList[number]; // this compiles to 'circle' | 'square'

const isCategory = (value: string) : value is Category => {
   return ALL_CATEGORIES.includes(value as Category )
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Fred Johnson