【问题标题】:How to tell TypeScript my function argument is an Enum key?如何告诉 TypeScript 我的函数参数是 Enum 键?
【发布时间】:2020-07-27 18:59:26
【问题描述】:

我有一个枚举,它将 HTTP 状态映射到他们的代码,如下所示:

我可以通过访问它们的密钥轻松获取这些代码(注意 IntelliSense 如何在右侧面板上显示 HttpStatus.NOT_FOUND = 404)

现在假设我有一个名为 sendStatus 的函数:

我应该如何输入这个函数才能让 IntelliSense 自动完成这些代码?

使用 keyof typeof 不起作用,因为它不会自动完成枚举值。

【问题讨论】:

  • 我只想将密钥作为字符串作为参数发送 (sendStatus("NOT_FOUND"),而不是 sendStatus(HttpStatus.NOT_FOUND)

标签: typescript visual-studio-code intellisense


【解决方案1】:

您可以通过运行这样的示例来测试keyof typeof,这表明 Enum 本身在您的情况下工作正常。

enum HttpStatus {
    OK = 200,
    CREATED = 201
}

function printStatus(code: keyof typeof HttpStatus) {
    const num = HttpStatus[code];
    if (num <= HttpStatus.CREATED) {
       console.log('HTTP Status key is: ', code);
       console.log('HTTP Status value is: ', num);
    }
}

printStatus("OK");

// Prints out
// > HTTP Status key is:  – "OK"
// > HTTP Status value is:  – 200
// Which shows that Enum value is being detected properly

keyof typeof 让您键入将所有 Enum 键表示为字符串的类型,这就是自动完成行为如此的原因。 https://www.typescriptlang.org/docs/handbook/enums.html#enums-at-compile-time

【讨论】:

  • 感谢您的回复!我只希望代码完成向我显示枚举值,与函数体无关......我想看到"BAD_REQUEST"......404 而不是"BAD_REQUEST"......BAD_REQUEST。显然keyof typeof 不是我要找的...
  • 如果不了解您的需求的更多上下文,这很难说,但是如果您希望自动完成以显示值,那么我建议使用枚举作为实际枚举,通过它们的键。它看起来像sendStatus(HttpStatus.OK)。 keyof typeof HttpStatus 返回类型 '"OK" | "CREATED"',并且该类型不知道实际原始 Enum 的数值。
【解决方案2】:

你想要的不是直接可能的。当您执行 keyof typeof 时,您会创建一个联合类型 'CREATED' | 'OK' | 'NOT_FOUND' ...,它与以前的枚举完全分开。

你能得到的最接近的就是做

function sendStatus(code: HttpStatus) {
    // code
}

send(HttpStatus.OK) // This will autocomplete and show the status code numbers

然后在 sendStatus 函数中将代码转换为字符串。

如果不知道你正在寻找的确切用法,很难说出你真正想要的东西,但我会考虑只使用一个普通的旧对象而不是枚举

const HTTP_STATUS = {'OK':200, 'CREATED':201} as const

然后,如果需要,您也可以像这样创建这两种类型

type StringStatus = keyof typeof HTTP_STATUS // 'OK' | 'CREATED'
type NumsStatus = (typeof HTTP_STATUS)[keyof typeof HTTP_STATUS] // 200 | 201

一般来说,在现代 TS 中使用 enums 很少有充分的理由。通常对象和/或联合类型做得更好。

【讨论】:

  • 我赞成你的答案(我完全错过了这个),因为它在诊断方面是正确的,但我不同意关于枚举的说法。如果在 OP 的情况下,同时具有字符串和数字表示形式是有价值的,那么 Enums 是理想的。更重要的是,我相信枚举具有性能优势,因为枚举只是作为整数进行传递和比较,即使在代码中您引用了它的字符串名称。虽然也许在现代 JS 引擎中,差异已经被优化掉了?
  • 感谢您的回复!所以我不是在与枚举打一场圣战,可能会有合法的用例。这也是个人喜好的问题,但我认为大多数时候你最好没有它们。 This answer 几乎解释了我对此的看法。
  • 顺便说一句:(typeof HTTP_STATUS)[keyof typeof HTTP_STATUS] 这种 Typescript 表达式记录在哪里?我可以看到它的行为......它本质上是一个地图操作。但在我说出你的答案之前,我永远不会知道你能做到这一点。
  • 我以前读过。它不包括您的用法,本质上是(type)[keys for that type] =&gt; values for that type as a union type。事实上,那个页面上连keyof typeof的组合都没有!
猜你喜欢
  • 1970-01-01
  • 2019-03-31
  • 2019-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多