打字稿扩展枚举

时间:2019-07-11 14:59:10

标签: typescript

情况是您有一个常量列表或Enum怎么办?

这是伪示例代码:

enum MyList
{
    A,
    B
}

enum MyList2
{
    C
}


function test<T>(input:MyList | T):void
{

}

test<MyList2>(123) // compiler does not identify that 123 is not a supported

1 个答案:

答案 0 :(得分:1)

这是一个带有数字枚举的longstanding issue。无论出于何种原因(某些向后兼容性都不会破坏),number被视为可分配给数字枚举,因此您可以做到这一点而不会出错:

enum E {
  V = 100
}
const num = 100;
const e: E = num; // no error ?

此外,数字枚举也旨在用于act as bit fields,因此,它们有意不要求数字枚举类型的值是特定的声明值之一:

enum Color {
  RED = 1,
  GREEN = 2,
  BLUE = 4
}
const red: Color = Color.RED; // 1
const yellow: Color = Color.RED | Color.GREEN; // 3 ?
const white: Color = Color.RED | Color.GREEN | Color.BLUE; // 7 ?
const octarine: Color = Math.pow(Color.BLUE - Color.RED, Color.GREEN); // 9 ?

是的,我不知道您为什么可以对数字枚举进行任何数学运算,但是您可以。结果是,基本上任何number都可以分配给任何数字枚举,反之亦然。


如果要防止这种情况,您可能希望放弃实际的枚举,而是使用自己控制的行为制作自己的类型和值。它比较冗长,但可以满足您的需求:

const MyList = {
  A: 0,
  B: 1
} as const;
type MyList = typeof MyList[keyof typeof MyList]

const MyList2 = {
  C: 0
} as const;
type MyList2 = typeof MyList2[keyof typeof MyList2]

这些行为与您的旧枚举类似(尽管有一些遗漏的类型),但是它们的行为将更加严格:

function test<T>(input: MyList | T): void {}

test(0); // okay
test(1); // okay
test(2); // okay, 2 is inferred as T
test<MyList2>(123); // error! 123 is not assignable to 0 | 1

好的,希望能有所帮助。祝你好运!

Link to code