In my project I need a number of string literal types and arrays of allowed values for variuos tasks like typeguards.
This is what we have:
type Animal = 'cat' | 'dog' | 'rabbit' | 'snake'
const animals: Animal[] = ['cat', 'dog', 'rabbit', 'snake']
It works, but it requires to list keys several times in source code.
Another way is to use enums as suggested in Get array of string literal type values but it creates overhead in runtime as compiled code for enum is bigger then array.
I found another way to do it that have no runtime overhead, but I'm not sure if it will work in the future, as it may be a bug.
const notWidened = <T extends string>(val: T[]) => val
const animals = notWidened(['cat', 'dog', 'rabbit', 'snake'])
type Animal = typeof animals[0]
So the question is if it's safe to use this snippet or it is going to break in the future. Is there a better way to get both literal string type and array without duplication.