Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal:symbol enum #18408

Open
kgtkr opened this issue Sep 12, 2017 · 9 comments
Open

proposal:symbol enum #18408

kgtkr opened this issue Sep 12, 2017 · 9 comments
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript

Comments

@kgtkr
Copy link

kgtkr commented Sep 12, 2017

I want symbol enum.

syntax example:

symbol enum Example{
  X,Y,Z
}

var Example;
(function (Example) {
    Example[Example["X"] = new Symbol("X")] = "X";
    Example[Example["Y"] = new Symbol("Y")] = "Y";
    Example[Example["Z"] = new Symbol("Z")] = "Z";
})(Example || (Example = {}));
@kgtkr kgtkr changed the title 【SUGGESTIONS】symbol enum proposal:symbol enum Sep 12, 2017
@mhegazy mhegazy added the Suggestion An idea for TypeScript label Sep 12, 2017
@mhegazy
Copy link
Contributor

mhegazy commented Sep 12, 2017

We first need a way to treat symbols as literals, just like string and numeric literals. this is covered in #15473

@nisimjoseph
Copy link

I see #15473 merged, does it mean we can use Symbols in Enum somehow?
I want to use Enum with the Types: string, number or Symbol.

@mhegazy mhegazy added the Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature label Jan 13, 2018
@fbartho
Copy link

fbartho commented Jan 18, 2018

Not to bikeshed, but wouldn't a more consistent syntax be:

enum Example: Symbol {
  X,Y,Z
}
// or
enum Example<Symbol> {
  X,Y,Z
}

Rather than introducing a new keyword of symbol these options either use inheritance style, or Generics, and would pave the way for arbitrary-valued enums?

@DanielRamosAcosta
Copy link

DanielRamosAcosta commented Jun 27, 2018

This would be very useful with Redux actions...

@Larry1123
Copy link

Is there something that would help move this issue?
If it would just be making a PR at this point I might be able to do it, may need to be guided in the right direction to start.

@littleclown
Copy link

I've found an alternative way to do it, and I hope it helps:

/**
 * Action types for StoreState.todo
 */
export namespace TodoActionTypes {
  // Adding todo item
  export const ADD_ITEM = Symbol('@todo/ADD_ITEM')
  export type ADD_ITEM = typeof ADD_ITEM

  // Removing todo item
  export const DEL_ITEM = Symbol('@todo/DEL_ITEM')
  export type DEL_ITEM = typeof DEL_ITEM

  // Performing undo on StoreState.todo
  export const UNDO = Symbol('@todo/UNDO')
  export type UNDO = typeof UNDO

  // Performing redo on StoreState.todo
  export const REDO = Symbol('@todo/REDO')
  export type REDO = typeof REDO
}


/**
 * Action types for StoreState.todo
 */
export type TodoActionTypes =
  | TodoActionTypes.ADD_ITEM
  | TodoActionTypes.DEL_ITEM
  | TodoActionTypes.UNDO
  | TodoActionTypes.REDO

@cosmoarunn
Copy link

cosmoarunn commented Oct 3, 2020

I've found an alternative way to do it, and I hope it helps:

/**
 * Action types for StoreState.todo
 */
export namespace TodoActionTypes {
  // Adding todo item
  export const ADD_ITEM = Symbol('@todo/ADD_ITEM')
  export type ADD_ITEM = typeof ADD_ITEM

  // Removing todo item
  export const DEL_ITEM = Symbol('@todo/DEL_ITEM')
  export type DEL_ITEM = typeof DEL_ITEM

  // Performing undo on StoreState.todo
  export const UNDO = Symbol('@todo/UNDO')
  export type UNDO = typeof UNDO

  // Performing redo on StoreState.todo
  export const REDO = Symbol('@todo/REDO')
  export type REDO = typeof REDO
}


/**
 * Action types for StoreState.todo
 */
export type TodoActionTypes =
  | TodoActionTypes.ADD_ITEM
  | TodoActionTypes.DEL_ITEM
  | TodoActionTypes.UNDO
  | TodoActionTypes.REDO

i guess this will do?

export type TodoActionTypes =
  | ADD_ITEM
  | DEL_ITEM
  | UNDO
  | REDO

@polomsky
Copy link

I have found another solution at https://fettblog.eu/symbols-in-javascript-and-typescript/ and I slightly improved it. Sadly, there is lot of code around it, but it gives pretty protection (compile time and runtime)

const COLOR_RED = Symbol('COLOR_RED');
const COLOR_ORANGE = Symbol('COLOR_ORANGE');

// intentionally not part of the enum for demonstration
const COLOR_GREEN = Symbol('COLOR_GREEN');

// freeze needed for runtime protection
export const colors = Object.freeze({
    COLOR_RED,
    COLOR_ORANGE,
} as const);

type ValuesWithKeys<T, K extends keyof T> = T[K];
type Values<T> = ValuesWithKeys<T, keyof T>

export type COLOR = Values<typeof colors>;

function foo(val: COLOR) {

}

foo(COLOR_RED);
foo(colors.COLOR_ORANGE);
foo(COLOR_GREEN); // refused by typescript

@alaboudi
Copy link

To continue on the same vein as this thread, I think enum values should be symbolic by default rather than integers. That's the whole point of enums to begin with. It would be best if developers don't even know the underlying value but rather treat enums as a union of interrelated Symbols. It would promote developers to have much better coding standards.

So something like

enum TrafficColors = {
 Red,
 Yellow,
 Green
}

would be best if translated into something like

var TrafficColors = {
 Red: Symbol('Red'),
 Yellow: Symbol('Yellow'),
 Green: Symbol('Green')
}

with keys used as the arguments in Symbol constructors to have google error reporting at runtime.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

10 participants