xgqfrms™, xgqfrms® : xgqfrms's offical website of cnblogs! xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!

TypeScript enum 枚举实现原理 All In One

TypeScript enum 枚举实现原理 All In One

反向映射 / 双向映射

https://www.typescriptlang.org/docs/handbook/enums.html

TS enum

enum Direction {
  Up,
  Down,
  Left,
  Right
}

TypeScript enum 枚举实现原理,反向映射


Direction = {}
// {}
Direction["Up"] = 0;
// 0
Direction;
// {Up: 0}
Direction["Left"] = 2
// 2
Direction;
// {Up: 0, Left: 2}


Direction[Direction["Left"] = 3] = "Left";
// 等价于 
const index = (Direction["Left"] = 3);
index;
// 3
Direction[index] = "Left";

"use strict";
var Direction;
(function (Direction) {
    Direction[Direction["Up"] = 1] = "Up";
    Direction[Direction["Down"] = 2] = "Down";
    Direction[Direction["Left"] = 3] = "Left";
    Direction[Direction["Right"] = 4] = "Right";
})(Direction || (Direction = {}));
// IIFE & return index as map dict

const log = console.log;

log(`Direction =`, Direction)

/*
{
  1: "Up", 2: "Down", 3: "Left", 4: "Right",
  Up: 1, Down: 2, Left: 3, Right: 4,
}

*/

JS enum

enum Direction {
  Up,
  Down,
  Left,
  Right
}

// js
var Direction;
(function (Direction) {
    Direction[Direction["Up"] = 0] = "Up";
    Direction[Direction["Down"] = 1] = "Down";
    Direction[Direction["Left"] = 2] = "Left";
    Direction[Direction["Right"] = 3] = "Right";
})(Direction || (Direction = {}));
// 等价于
function enum_generator(arr = []) {
  let result = {};
  for(const [i, item] of arr.entries()) {
    // console.log(`i, item`, i, item)
    result[result[item] = i] = item;
  }
  return result;
}

const Directions = enum_generator(["Up","Down","Left","Right"]);

// 利用了js 对象赋值的返回值就是所赋值的特性
obj = {};
{}
obj['Up'] = 0;
// 0
obj[0] = "Up";
// 'Up'

image

demos

"use strict";

/**
 *
 * @author xgqfrms
 * @license MIT
 * @copyright xgqfrms
 * @created 2020-10-21
 * @modified
 *
 * @description
 * @augments
 * @example
 * @link
 *
 */

const log = console.log;

function logString(msg: string): void {
  log(`message =`, msg)
}

function logNumber(msg: number): void {
  log(`message =`, msg)
}


// 👍 number enum
enum DirectionNumber {
  Up,
  Down,
  Left,
  Right
}
// 👎 number enum with change index
enum DirectionIndex {
  Up = 3,
  Down,
  Left,
  Right
}

// 👎 string & number mixed enum
enum DirectionMixed {
  Up = "up",
  Down = 1,
  Left,
  Right
}

// 👍 string enum
enum Level {
  A = "perfect",
  B = "good",
  C = "bad",
}

// 👍 const enum
const enum Roles {
  Admin,
  User,
  Operator,
}

//number enum
enum Direction {
  Up = 1,
  Down,
  Left,
  Right
}

// TypeScript enum 枚举实现原理,反向映射
// Direction ={
//   1: "Up", 2: "Down", 3: "Left", 4: "Right",
//   Up: 1, Down: 2, Left: 3, Right: 4,
// }

logString(Level.A);

logNumber(Direction.Down);

logNumber(Roles.Admin);
// console.log(0 /* Admin */);

"use strict";
/**
 *
 * @author xgqfrms
 * @license MIT
 * @copyright xgqfrms
 * @created 2020-10-21
 * @modified
 *
 * @description
 * @augments
 * @example
 * @link
 *
 */
var log = console.log;
function logString(msg) {
    log("message =", msg);
}
function logNumber(msg) {
    log("message =", msg);
}
// 👍 number enum
var DirectionNumber;
(function (DirectionNumber) {
    DirectionNumber[DirectionNumber["Up"] = 0] = "Up";
    DirectionNumber[DirectionNumber["Down"] = 1] = "Down";
    DirectionNumber[DirectionNumber["Left"] = 2] = "Left";
    DirectionNumber[DirectionNumber["Right"] = 3] = "Right";
})(DirectionNumber || (DirectionNumber = {}));
// 👎 number enum with change index
var DirectionIndex;
(function (DirectionIndex) {
    DirectionIndex[DirectionIndex["Up"] = 3] = "Up";
    DirectionIndex[DirectionIndex["Down"] = 4] = "Down";
    DirectionIndex[DirectionIndex["Left"] = 5] = "Left";
    DirectionIndex[DirectionIndex["Right"] = 6] = "Right";
})(DirectionIndex || (DirectionIndex = {}));
// 👎 string & number mixed enum
var DirectionMixed;
(function (DirectionMixed) {
    DirectionMixed["Up"] = "up";
    DirectionMixed[DirectionMixed["Down"] = 1] = "Down";
    DirectionMixed[DirectionMixed["Left"] = 2] = "Left";
    DirectionMixed[DirectionMixed["Right"] = 3] = "Right";
})(DirectionMixed || (DirectionMixed = {}));
// 👍 string enum
var Level;
(function (Level) {
    Level["A"] = "perfect";
    Level["B"] = "good";
    Level["C"] = "bad";
})(Level || (Level = {}));
//number enum
var Direction;
(function (Direction) {
    Direction[Direction["Up"] = 1] = "Up";
    Direction[Direction["Down"] = 2] = "Down";
    Direction[Direction["Left"] = 3] = "Left";
    Direction[Direction["Right"] = 4] = "Right";
})(Direction || (Direction = {}));
// TypeScript enum 枚举实现原理,反向映射
// Direction ={
//   1: "Up", 2: "Down", 3: "Left", 4: "Right",
//   Up: 1, Down: 2, Left: 3, Right: 4,
// }
logString(Level.A);
logNumber(Direction.Down);
logNumber(0 /* Admin */);

tsconfig bug ???

const timestamp = Date.now();
// const timestamp = new Date().getTime();
// 👍 computed enum
const enum Dynamic {
  role = Roles.User,
  level = Level.A,
  // time = Date.now(),
  // time = new Date().getTime(),
  time = timestamp,
  // time = Math.random(),
  value = 1 + 2,
  len = "123".length,
}
// const enum member initializers can only contain literal values and other computed enum values.

OK

computed enum ❌ const bug

remove const keyword ✅


// 👍 computed enum ❌ const bug
// const enum DynamicConstBug {
//   role = Roles.User,
//   level = Level.A,
//   time = Date.now(),
//   timestamp = new Date().getTime(),
//   random = Math.random(),
//   value = 1 + 2,
//   len = "123".length,
// }
// const enum member initializers can only contain literal values and other computed enum values.

// 👍 computed enum ✅
enum Dynamic {
  role = Roles.User,
  level = Level.A,
  time = Date.now(),
  timestamp = new Date().getTime(),
  random = Math.random(),
  value = 1 + 2,
  len = "123".length,
}

enum & for loop

for...in

// enum 本质上是一个 js 对象
enum HTTPTypes {
  get = 'get',
  post = 'delete',
  put = 'put',
  delete = 'delete',
}


const HTTP: {[k: string]: any} = {};

for (let key in HTTPTypes) {
  console.log('key =', key);
  HTTP[key] = HTTPTypes[key] ;
}

export default {
  HTTP,
};

generic & keyof

// 多个泛型参数
// O extends object
// K extends keyof O = keyof O
function enumKeys<O extends object, K extends keyof O = keyof O>(obj: O): K[] {
    return Object.keys(obj).filter(k => Number.isNaN(+k)) as K[];
}

function log(value: Color) {
    console.log(`Value: ${value}`);
}

for (const value of enumKeys(Color)) {
    log(Color[value]);
}

https://www.petermorlion.com/iterating-a-typescript-enum/

https://stackoverflow.com/questions/39372804/how-can-i-loop-through-enum-values-for-display-in-radio-buttons

errors

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'typeof ???'.

enum HTTPTypes {
  get = 'get',
  post = 'delete',
  put = 'put',
  delete = 'delete',
}

const HTTP: {
  // [key: string]: any,
  [key: string]: string,
} = {};

for (let key in HTTPTypes) {
  console.log('key =', key);
  HTTP[key] = HTTPTypes[key as keyof object];
  // Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'typeof HTTPTypes'.
  // HTTP[key] = HTTPTypes[key];
}

https://stackoverflow.com/questions/57086672/element-implicitly-has-an-any-type-because-expression-of-type-string-cant-b

(🐞 反爬虫测试!打击盗版⚠️)如果你看到这个信息, 说明这是一篇剽窃的文章,请访问 https://www.cnblogs.com/xgqfrms/ 查看原创文章!

REPL

TypeScript: TS Playground - An online editor for exploring TypeScript and JavaScript

https://www.typescriptlang.org/play?#code/Q

refs

https://www.typescriptlang.org/docs/handbook/enums.html

https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#enums



©xgqfrms 2012-2021

www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!

原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!


posted @ 2020-10-26 22:15  xgqfrms  阅读(593)  评论(10编辑  收藏  举报