I have an enum which is defined like this:
enum Ed {
up,
down,
left,
right,
}
//or
enum Es {
A = "a",
B = "b",
C = "c",
}
So given value Es.B
, I want to get the next one which is Es.C
Something like Es.B+1
or getNextEnum(Es.B)
or EnumX.of(Es).next(Es.B)
or even simpler? Function should support any enum, so no hardcoded values please.
Note: Next of last element is expected to be the first element of enum.
Thanks
Here is the answer which works for both numeric and string enums:
class EnumX {
static of<T extends object>(e: T) {
const values = Object.values(e)
const vLen = values.length
const isNumEnum = e[e[values[0]]] === values[0]
return isNumEnum ? {
next: <K extends keyof T>(v: T[K]) => values[(values.indexOf(v) + 1) % (vLen / 2) + vLen / 2],
prev: <K extends keyof T>(v: T[K]) => values.at((values.indexOf(v) - 1) % (vLen / 2) + vLen / 2)
} : {
next: <K extends keyof T>(v: T[K]) => values[(values.indexOf(v) + 1) % vLen],
prev: <K extends keyof T>(v: T[K]) => values.at((values.indexOf(v) - 1) % vLen)
}
}
}
This also provides functions for both next and previous values.
Usage example:
enum Es {
A = "a",
B = "b",
C = "c",
}
const esx = EnumX.of(Es)
console.log(esx.next(Es.A), esx.next(Es.B), esx.next(Es.C)); // "b", "c", "a"
console.log(esx.prev(Es.A), esx.prev(Es.B), esx.prev(Es.C)); // "c", "a", "b"
enum En {
A,
B,
C,
}
const enx = EnumX.of(En)
console.log(enx.next(En.A), enx.next(En.B), enx.next(En.C)); // 1, 2, 0
console.log(enx.prev(En.A), enx.prev(En.B), enx.prev(En.C)); // 2, 0, 1
Thanks @alx for inspiration