node.js - typescript ,带有字符串和数字的枚举

标签 node.js typescript

我有一个接口(interface)

interface mathTest {
   mathAction: MathActionEnum;
}

这样做的原因是我希望此属性仅具有下面枚举中的特定值之一。

enum MathActionEnum {
    'byOne' = 1,
    'byTwo' = 2,
    'byFour' = 4,
    'byEight' = 8,
}

假设 mathAction = 'byOne' -> 从 API 响应中收到。

第一种情况:进行算术运算,我需要数值:let result: number = amount/MathActionEnum[mathAction] 但出现错误:

The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type

它是一个数字,但我仍然需要使用 Number(MathActionEnum[mathAction]) 来转换它才能消除错误。

第二种情况:相等检查,我需要字符串值:if (mathAction === MathActionEnum[MathActionEnum.byOne]) 但出现错误:

This condition will always return 'false' since the types 'MathActionEnum' and 'string' have no overlap

这很有道理。

我有点迷失了,有没有办法按照我的预期来编写它的语法?也许我需要以不同的方式定义事物? 谢谢

最佳答案

TypeScript 枚举绝对不适合任何类型的键值映射。其目的是拥有一组唯一可识别的标签,但标签就是它的终点。虽然它们实际上可能在底层有数字表示,但它们并不打算用作键值存储。您必须将其转换为“提取数字”,然后类型只是数字,因此您实际上违背了枚举的目的。

出于所有意图和目的,请将它们视为没有有用值的键:

const MathActionEnum = Object.freeze({
  byOne: Symbol(),
  byTwo: Symbol(),
  byFour: Symbol(),
  byEight: Symbol(),
})

考虑更新的替代方案,const assertion , 反而。它们将为您提供键和值的类型安全性:

const MathActions = {
  'byOne': 1,
  'byTwo': 2,
  'byFour': 4,
  'byEight': 8,
} as const

type MathAction = keyof typeof MathActions

type MathActionValue = typeof MathActions[MathAction]

您可以在键和值上获得完整的类型安全性:

const example = (action: MathAction) => {
    return 2 * MathActions[action]
}

example('byOne')

// compile error, not a valid key
example('foo')

 // -------------
const example2 = (actionValue: MathActionValue) => {
    return 2 * actionValue
}

example2(4)

// compile error, not a valid value
example2(19)

您甚至可以添加类型断言来检查任意值是否是键或值:

const isAction = (action: string): action is MathAction => {
    return Object.keys(MathActions).includes(action)
}
isAction

const isActionValue = (actionValue: number): actionValue is MathActionValue => {
    return Object.values(MathActions).includes(actionValue as any)
}

您甚至可以获得键和值的 IDE 自动完成功能:

enter image description here

这是一个Playground

关于node.js - typescript ,带有字符串和数字的枚举,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74353013/

相关文章:

reactjs - Typescript上传目录,类型上不存在属性 'directory'

javascript - 如何在进行大量更改的同时运行我的 MEAN 堆栈代码,而无需重新启动 `npm start` ?

javascript - 使 Socket.io 路径与 NGiNX proxy_pass 一起使用

node.js - 获取node.js程序中所需的所有文件

javascript - 用户数据未使用 Node API 插入 mongodb

typescript - 如何将 plotly.js 导入 TypeScript?

css - 如何创建 Material Design 径向 react 动画

javascript - SheetJS:将行值从数组转置到对象

node.js - 从同一主机的 SSL Apache 请求访问非 SSL socket.io (nodejs) 服务器

typescript - TypeScript 编译器选项的模块加载顺序不正确 "module": "es2015"