Skip to content

不推荐使用 Enum 类型 #21

@nmsn

Description

@nmsn

来源:https://react-typescript-cheatsheet.netlify.app/docs/basic/troubleshooting/types

推荐使用联合类型代替枚举类型

枚举的问题

  1. enum 编译后的内容庞大(使用 const enum 能解决这个问题,但容易混淆)
enum Direction {
  Up,
  Down,
  Left,
  Right,
}

// output
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 = {}));
  1. 数字类型的枚举不安全(字符串没事)
enum Direction {
  Up,
  Down,
  Left,
  Right,
}

function move(direction: Direction) {
    console.log(direction);
}

move(30); // ok

这种执行不会报错

  1. 字符串枚举不能直接使用字符串赋值
enum Status {
  Admin = "Admin",
  User = "User",
  Moderator = "Moderator",
}

declare function closeThread(threadId: number, status: Status): void;

closeThread(10, "Admin");
//              ^ 💥 This is not allowed!


closeThread(10, Status.Admin);
//              ^ You have to be explicit!

使用联合类型更好

  1. 简单形式
type Status = "Admin" | "User" | "Moderator"

declare function closeThread(threadId: number, status: Status): void;

closeThread(10, "Admin");
// All good 😄
  1. 类枚举风格
const Direction = {
  Up: 0,
  Down: 1,
  Left: 2,
  Right: 3,
} as const;

// Get to the const values of any object
type Values<T> = T[keyof T];

// Values<typeof Direction> yields 0 | 1 | 2 | 3
declare function move(
  direction: Values<typeof Direction>): void;

move(30);
//   ^ 💥 This breaks!

move(0);
//   ^ 👍 This works!

move(Direction.Left);
//   ^ 👍 This also works!

// And now for the Status enum

const Status = {
  Admin: "Admin",
  User: "User",
  Moderator: "Moderator"
} as const;

// Values<typeof Status> yields "Admin" | "User" | "Moderator"
declare function closeThread(
  threadId: number, 
  status: Values<typeof Status>): void;

closeThread(10, "Admin"); // All good!
closeThread(10, Status.User); // enum style

这些方法不会导致出现枚举存在的问题

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions