Typescript 枚举小技巧

233 阅读2分钟

0. Enum 是什么?

枚举是常量的集合 (对象格式)

enum Colors {
  RED = 'red',
  WHITE = 'white',
  BLUE = 'blue'
}

如何在ES5中实现类似的常量的集合?Object.freeze

const Pizzas = Object.freeze({
  PEPPERONI: true,
  CHEESE: true,
  PINEAPPLE: false,
});

Object.freeze()允许您创建一个不可变的对象,这意味着在定义后不能更改任何属性值。

1. Enum => String

在写类型的时候,经常会遇到枚举值的情况,比如

export enum CanvaType {
  lattice = 'lattice', // 点阵图
  grid = 'grid', // 网格图
  strip = 'strip', // 条纹图
}
export const Canva = (props: {type: CanvaType}) => {
  return <canva className={props.type}/>
}

然后像这样使用组件:

import {Canva, CanvaType} from "./Canva";

return (
	<Canva type={CanvaType.grid}>
)

但这不符合用户习惯对不对?我们需要兼容用户直接输入字符串的情况。如果我改成 type='grid',tslint就会提示错误,不接受字符串,只接受枚举

image.png

但这不符合用户习惯对不对?所以我们需要兼容用户直接输入字符串的情况。

keyof typeof 可以用于获取有关可用字符串键,此时我们只需要对组件进行改造:

export const Canva = (props: {type: keyof typeof CanvaType}) => {
  return <canva className={props.type}/>
}

然后就可以在开发的时候获得良好的提示!

image.png

是不是 nice 起来了!

2. Unknown Enum 的推断

为不确定的枚举值添加类型推断。

有确定性的枚举,但也接受不确定的值,并希望其能给到一些有意义的提示

案例:

关键代码 string & {}

const knownColors = {
    green: "#66bb6a",
    red: "#ef9a9a",
    blue: "#81d4fa",
} as const;

function getColor(color: (keyof typeof knownColors) | (string & {})): string {
    if (color in knownColors)
        return knownColors[color as keyof typeof knownColors];
    return color;
}

getColor("red"); // okay
getColor("mauve"); // okay
getColor(123); // error

IDE的提示效果:

image.png

其他做法:函数重载,也能达到一样的效果

function getColorOvld(color: (keyof typeof knownColors)): string;
function getColorOvld(color: string): string;
function getColorOvld(color: string): string {
    if (color in knownColors)
        return knownColors[color as keyof typeof knownColors];
    return color;
}

getColorOvld("red"); // okay
getColorOvld("mauve"); // okay
getColorOvld(123); // error

参考链接: