Skip to content

Instantly share code, notes, and snippets.

@samuelgoto
Last active October 25, 2017 00:05
Show Gist options
  • Select an option

  • Save samuelgoto/405251eb4fd7b42d764589418ea2afc4 to your computer and use it in GitHub Desktop.

Select an option

Save samuelgoto/405251eb4fd7b42d764589418ea2afc4 to your computer and use it in GitHub Desktop.

This is a very early stage 0 exploration to add enums to Javascript, as a syntatic simplication over a common pattern to define enumerations.

Introduction

Enums come up often in code bases (TODO: try to estimate a number) and it is easy to get it incorrectly. Specifically, it is easy to forget:

  • to Object.freeze the object
  • to declare it as a const which avoids having the symbol redefined

With this in mind, we propose a nem keyword to javascript, say enum which de-sugars to the following:

// if you write this ...
enum Foo {
  BAR: 1,
  HELLO "hello",
  WORLD: false
}

// ... it gets de-sugared to:
const Foo = Objec.freeze({
  BAR: 1,
  HELLO: "hello",
  WORLD: false
});

// TODO(goto): should we use Symbols here for extra type safety?
@samuelgoto
Copy link
Author

samuelgoto commented Oct 24, 2017

Examples

https://github.com/jspears/subschema/blob/master/src/listenUtil.js#L144

/**
 * The possible types of listeners that can be added.
 * @readonly
 * @enum {string}
 */
export const MapTypes = {
    'value': 'addListener',
    'error': 'addErrorListener',
    'submit': 'addSubmitListener',
    'state': 'addStateListener',
    'validate': 'addValidateListener',
    'addListener': 'addListener',
    'addErrorListener': 'addErrorListener',
    'addSubmitListener': 'addSubmitListener',
    'addStateListener': 'addStateListener',
    'addValidateListener': 'addValidateListener'
}

https://github.com/WaffleBoardWizard/guild-ball-simulator/blob/04ae96c7561e7b9c3c0959134a34f6a6c3708a58/gb-simulator-web/src/components/Controls/GameBoard/Inputs.js#L1

import Enum from "es6-enum"

export default Enum(
  "PIECE_CLICK",
  "PIECE_DRAG",
  "CLICK_MENU_BUTTON");

https://github.com/Piicksarn/cdnjs/blob/master/ajax/libs/Shuffle/2.0.6/jquery.shuffle.js#L103

jquery

/**
 * Events the container element emits with the .shuffle namespace.
 * For example, "done.shuffle".
 * @enum {string}
 */
Shuffle.EventType = {
  LOADING: 'loading',
  DONE: 'done',
  SHRINK: 'shrink',
  SHRUNK: 'shrunk',
  FILTER: 'filter',
  FILTERED: 'filtered',
  SORTED: 'sorted',
  LAYOUT: 'layout',
  REMOVED: 'removed'
};

angular

https://github.com/angular/bower-material/blob/master/modules/js/panel/panel.js#L2504

/**
 * Possible default closeReasons for the close function.
 * @enum {string}
 */
MdPanelRef.closeReasons = {
  CLICK_OUTSIDE: 'clickOutsideToClose',
  ESCAPE: 'escapeToClose',
};

https://github.com/mirror/chromium/blob/master/chrome/browser/resources/settings/site_settings/constants.js

/**
 * All possible contentSettingsTypes that we currently support configuring in
 * the UI. Both top-level categories and content settings that represent
 * individual permissions under Site Details should appear here.
 * This should be kept in sync with the |kContentSettingsTypeGroupNames| array
 * in chrome/browser/ui/webui/site_settings_helper.cc
 * @enum {string}
 */
settings.ContentSettingsTypes = {
  COOKIES: 'cookies',
  IMAGES: 'images',
  JAVASCRIPT: 'javascript',
  SOUND: 'sound',
  PLUGINS: 'plugins',  // AKA Flash.
  POPUPS: 'popups',
  GEOLOCATION: 'location',
  NOTIFICATIONS: 'notifications',
  MIC: 'media-stream-mic',  // AKA Microphone.
  CAMERA: 'media-stream-camera',
  PROTOCOL_HANDLERS: 'register-protocol-handler',
  UNSANDBOXED_PLUGINS: 'ppapi-broker',
  AUTOMATIC_DOWNLOADS: 'multiple-automatic-downloads',
  BACKGROUND_SYNC: 'background-sync',
  MIDI_DEVICES: 'midi-sysex',
  USB_DEVICES: 'usb-chooser-data',
  ZOOM_LEVELS: 'zoom-levels',
  PROTECTED_CONTENT: 'protectedContent',
  ADS: 'ads',
};

Azure

https://github.com/Azure/azure-storage-node/blob/master/lib/common/util/constants.js

/**
  * Defines the service types indicators.
  * 
  * @const
  * @enum {string}
  */
  ServiceType: {
    Blob: 'blob',
    Queue: 'queue',
    Table: 'table',
    File: 'file'
  },

  /**
  * Specifies the location used to indicate which location the operation can be performed against.
  *
  * @const
  * @enum {int}
  */
  RequestLocationMode: {
    PRIMARY_ONLY: 0,
    SECONDARY_ONLY: 1,
    PRIMARY_OR_SECONDARY: 2
  },

  /**
  * Represents a storage service location.
  *
  * @const
  * @enum {int}
  */
  StorageLocation: {
    PRIMARY: 0,
    SECONDARY: 1
  },

@samuelgoto
Copy link
Author

BigQuery

SELECT
  sample_path,
  sample_repo_name,
  content
FROM [bigquery-public-data:github_repos.sample_contents]
WHERE
  sample_path LIKE '%.js' and
  content LIKE '%@enum%' and
  not content LIKE '%goog%'
  
limit 100;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment