1

Let's say, MyEnum is a TS Enum of this kind (numeric, continuous):

export enum MyEnum { 
    optionOne, 
    optionTwo,
    // more opions ...
}

and I want to increment it by one and use the result as a parameter for the next method call. This makes the compiler happy:

private DoSomething(currentValue: MyEnum): void {
    let nextEnumValue = <MyEnum>(<number><unknown>currentValue + 1);
    this.DoMore(nextEnumValue);
}

private DoMore(currentValue: MyEnum): void {
    // Something ...
}

Is there an easier (and type-safer) way to obtain nextEnumValue?

EluciusFTW
  • 2,565
  • 6
  • 42
  • 59

1 Answers1

3

I would suggest keeping this behaviour with the enum, so that it's more obvious it needs to be updated (or at least reviewed) if any change is made to the values. For example, using the namespace idea from Fenton's answer here:

enum Color {
    RED,
    GREEN,
    BLUE
}

namespace Color {
  export function after(value: Color): Color {
      return value + 1;
  }
}

// In use
const color: Color = Color.after(Color.RED);

This doesn't require any type assertions (because Color is effectively 0 | 1 | 2, a subset of number), and will start throwing a compiler error if you add non-numeric values to the enumeration. However note that the compiler will not have a problem with a change to non-consecutive but still numeric values, e.g. changing to bit flag-style values:

enum Color {
  RED = 1,
  GREEN = 2,
  BLUE = 4
}

You'd have to have other tests to catch issues like that. It also doesn't deal with the fact that, either way, Color.after(Color.BLUE) doesn't have a meaningful value.

Playground

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
  • The new typescript doesnt like this due to https://github.com/typescript-eslint/typescript-eslint/blob/v2.34.0/packages/eslint-plugin/docs/rules/no-namespace.md is there any other modern ways to do this? – Saba Ahang Feb 15 '21 at 14:50
  • @SabaAhang you can see the other ways to add functions to an enum on the question I linked, or you can write [a vanilla function](https://www.typescriptlang.org/play?#code/KYOwrgtgBAwg9gGzgJygbwFBSgJQKIAiANFlAOL54ByJ2AQgDICqeGAvhhgGZggDGAFwCWcEFD6IUAQS4DgyABQA3AIYIwwAFyxJyAJTb4SVJmzJgAsMjGr1wKAGooARnYYgA) rather than have it as a method on the enum, or you can just disable that linting rule. – jonrsharpe Feb 15 '21 at 14:54