gpt4 book ai didi

TypeScript:为什么不强制执行精确的枚举类型?

转载 作者:搜寻专家 更新时间:2023-10-30 20:40:28 27 4
gpt4 key购买 nike

请看一下这段简单的代码:

const enum MyEnum {
Zero
}

const foo: MyEnum.Zero = 0 // OK as expected (since MyEnum.Zero is zero)
const bar: MyEnum.Zero = 1 // OK, but expected Error! Why?

在这种情况下,我如何强制执行精确、窄的数字类型,即 0

Playground

UPD:枚举似乎被破坏了 https://github.com/microsoft/TypeScript/issues/11559

最佳答案

the enum section of the TypeScript handbook 中并没有真正提及,但是所有 number 值都可以分配给任何数字枚举类型。 TypeScript 手册的另一份草稿说 the following :

https://www.typescriptlang.org/docs/handbook/type-compatibility.html#enums

A few of the [assignability] rules are odd because of historical restrictions. For example, any number is assignable to a numeric enum, but this is not true for string enums. Only strings that are known to be part of a string enum are assignable to it. That's because numeric enums existed before union types and literal types, so their rules were originally looser.

目前在 a section on type compatibility 中提到数字枚举和 number 是可以相互赋值的。

TypeScript 中的数字枚举历来用于支持 bit fields ,使用位掩码和按位操作组合显式声明的枚举值以获得新值:

enum Color {
Red = 0xFF0000,
Green = 0x00FF00,
Blue = 0x0000FF
}
const yellow: Color = Color.Red | Color.Green; // 0xFFFF00
const white: Color = Color.Red | Color.Green | Color.Blue; // 0xFFFFFF
const blue: Color = white & ~yellow; // 0x0000FF

并且因为枚举的这种使用存在于现实世界的代码中,所以改变这种行为将是一个重大变化 (see comment on microsoft/TypeScript#8020)。而且该语言的维护者似乎并不特别愿意尝试(参见 microsoft/TypeScript#22311 )。

因此,无论好坏,数字枚举都是松散类型的,主要与 number 同义。


可以推出你自己的更严格的类似枚举的对象,但它涉及手动完成许多当你使用 enum 语法时自动发生的事情。这是一个可能的实现(它不会给你一个 reverse mapping ):

namespace MyEnum {
export const Zero = 0;
export type Zero = typeof Zero;

export const One = 1;
export type One = typeof One;

export const Two = 2;
export type Two = typeof Two;
}
type MyEnum = typeof MyEnum[keyof typeof MyEnum];

const foo: MyEnum.Zero = 0 // okay
const bar: MyEnum.Zero = 1 // error!

其工作原理如下...当您编写 enum X { Y = 123, Z = 456 } 时,TypeScript 在运行时引入一个名为 X 的值,具有属性X.YX.Z。它还引入了名为XX.YX.Z类型X.YX.Z 类型只是值 X.YX.Z 的类型。但是类型 X 不是值 X 的类型。相反,它是属性类型 X.Y | 的并集。 X.Z.

我在上面使用了namespaceexportconsttype来实现类似的效果。但这里的不同之处在于,数字枚举的可分配性规则不适用,因此您会得到您期望的严格类型检查。

Link to code

关于TypeScript:为什么不强制执行精确的枚举类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57334349/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com