Skip to content

Instantly share code, notes, and snippets.

@kourge
Last active March 23, 2017 00:05
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kourge/974e28ba84f60da376889512a9677fce to your computer and use it in GitHub Desktop.
Save kourge/974e28ba84f60da376889512a9677fce to your computer and use it in GitHub Desktop.
String enums in TypeScript
export enum Event1 {
SIGN_IN_WALL = 'Sign In Wall' as any,
SIGN_UP = 'Sign Up' as any,
}
{
const x = Event1.SIGN_UP; // type = Event1
const y: number = x;
// Verdict: approach is succint, but incorrectly allows type widening to number.
}
/**/
export namespace Event2 {
export const SIGN_IN_WALL = 'Sign In Wall';
export const SIGN_UP = 'Sign Up';
export type Type = (
typeof SIGN_IN_WALL |
typeof SIGN_UP
);
}
{
const x = Event2.SIGN_UP; // type = 'Sign Up'
const y: string = x;
// Verdict: approach is tedious, but type safe.
}
/**/
// An extension of:
// https://github.com/Microsoft/TypeScript/issues/3192#issuecomment-261720275
function Enum<
Value extends string
>(...values: Value[]): {[K in Value]: K};
function Enum<
Shape extends { [key: string]: Value },
Value extends string
>(definition: Shape): Shape;
function Enum(...values: any[]): object {
if (typeof values[0] === 'string') {
const result: any = {};
for (const value of values) {
result[value] = value;
}
return result;
} else {
return values[0];
}
}
type Enum<T extends object> = T[keyof T];
namespace Enum {
export function keys<
Shape extends { [key: string]: any }
>(e: Shape): (keyof Shape)[] {
return Object.keys(e) as (keyof Shape)[];
}
export function values<
Shape extends object
>(e: Shape): Enum<Shape>[] {
const result: Enum<Shape>[] = [];
for (const key of keys(e)) {
result.push(e[key as string]);
}
return result;
}
}
const Event3 = Enum({
SIGN_IN_WALL: 'Sign In Wall',
SIGN_UP: 'Sign Up'
});
type Event3 = Enum<typeof Event3>;
{
const x = Event3.SIGN_UP; // type = 'Sign Up'
const y: string = x;
// Verdict: Succinct *and* type safe.
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment