Skip to content

Instantly share code, notes, and snippets.

@AuthorProxy
Created July 24, 2021 00:50
Show Gist options
  • Select an option

  • Save AuthorProxy/7ebd793e5e4ad28105218aa3cd395ddf to your computer and use it in GitHub Desktop.

Select an option

Save AuthorProxy/7ebd793e5e4ad28105218aa3cd395ddf to your computer and use it in GitHub Desktop.
3 types of TypeScript Enums
//////////////////////////////////////////////////////////////
export const buttonSizes_1 = ['small', 'medium'] as const
export type ButtonSize_1 = typeof buttonSizes_1[number]
function test_1(_: ButtonSize_1) {
console.assert(buttonSizes_1.includes(_))
}
test_1('medium') // we can do this
test_1(ButtonSize_1.small) // we can't do this
// Conclusion
// 1. Enum can be implicitly used
// 2. Enum cannot be explicitly used
// 3. IDE will not know where this Enum is used
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
enum ButtonSize_2 {
small = 'small',
medium = 'medium'
}
const buttonSizes_2 = Object.values(ButtonSize_2)
function test_2(_: ButtonSize_2){
console.assert(buttonSizes_2.includes(_))
}
test_2(ButtonSize_2.medium) // we can do this
test_2('small') // we can't do this
// Conclusion
// 1. Enum cannot be implicitly used
// 2. Enum can be explicitly used
// 3. IDE will know where this Enum is used
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
const ButtonSize_3 = Enum('small', 'medium')
type ButtonSize_3 = Enum<typeof ButtonSize_3>
const buttonSizes_3 = Object.values(ButtonSize_3)
function test_3(_: ButtonSize_3){
console.assert(buttonSizes_3.includes(_))
}
test_3(ButtonSize_3.medium) // we can do this
test_3('small') // we can do this
// Conclusion
// 1. Enum can be implicitly used
// 2. Enum can be explicitly used
// 3. IDE will not know where this Enum is used when using implicit enum
//////////////////////////////////////////////////////////////
type UnionFromTuple<T> = T extends (infer U)[] ? U : never
type Enum<T extends object> = T[keyof T]
function Enum <T extends string[]>(...args: T) {
return Object.freeze(args.reduce((acc, next) => {
return {
...acc,
[next]: next,
}
}, Object.create(null)) as { [P in UnionFromTuple<typeof args>]: P })
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment