[英]Using `enum` in ternary operator TypeScript
I am trying to set an object with a ternary operator based on a config value and an enum
我正在尝试使用基于配置值和
enum
的三元运算符设置 object
import { config } from 'src/config'
import {logLevelEnum} from 'a-package-installed'
const someObject = {
logLevel: config.logLevel ? logLevelEnum[config.logLevel] : logLevelEnum.NOTHING,
}
The enum
is basically this: enum
基本上是这样的:
export enum logLevelEnum {
NOTHING = 0,
ERROR = 1,
WARN = 2,
INFO = 4,
DEBUG = 5,
}
But I get the compilation error:但是我得到编译错误:
Element implicitly has an 'any' type because index expression is not of type 'number'.
logLevel: config.logLevel ? logLevelEnum[config.logLevel] : logLevelEnum.NOTHING,
~~~~~~~~~~~~~~~
But I don't understand why it says that the index expression is supposed to be number
since is an enum
.但我不明白为什么它说索引表达式应该是
number
,因为它是一个enum
。
Can someone explain to me why and how can I achieve what I need?有人可以向我解释为什么以及如何实现我所需要的吗?
Much appreciated.非常感激。
The problem is that config.logLevel
is of type string
while there is actually only a subset of valid strings.问题是
config.logLevel
是string
类型,而实际上只有一部分有效字符串。
So declare config.logLevel
as a union type: 'NOTHING' | 'ERROR' | 'WARN' | 'INFO' | 'DEBUG'
所以将
config.logLevel
声明为联合类型: 'NOTHING' | 'ERROR' | 'WARN' | 'INFO' | 'DEBUG'
'NOTHING' | 'ERROR' | 'WARN' | 'INFO' | 'DEBUG'
This union type doesn't seem to be generatable from the enum
according to this: Generic type to get enum keys as union string in typescript?根据以下内容,此联合类型似乎无法从
enum
中生成: Generic type to get enum keys as union string in typescript?
Related Typescript Playground Example相关Typescript 游乐场示例
You can access your enum in different ways:您可以通过不同的方式访问您的枚举:
logLevelEnum.WARN
= 2
: by the enum directly logLevelEnum.WARN
= 2
: 直接通过枚举logLevelEnum['WARN']
= 2
: via index operator logLevelEnum['WARN']
= 2
:通过索引运算符logLevelEnum[2]
= WARN
: get the enum-name from an enum-value logLevelEnum[2]
= WARN
:从枚举值中获取枚举名When you try to access an invalid enum, you get undefined
at runtime.当您尝试访问无效枚举时,您会在运行时得到
undefined
。 Typescript tries to avoid this situation and gives you a compile error when possible to avoid this: Typescript 试图避免这种情况,并在可能的情况下给你一个编译错误来避免这种情况:
logLevelEnum.warning
: Property 'warning' does not exist on type 'typeof logLevelEnum'. logLevelEnum.warning
:属性“warning”在类型“typeof logLevelEnum”上不存在。logLevelEnum['warning']
= undefined
: Element implicitly has an 'any' type because index expression is not of type 'number'. logLevelEnum['warning']
= undefined
:元素隐式具有 'any' 类型,因为索引表达式不是 'number' 类型。
any
(and not logLevelEnum
or logLevelEnum | undefined
, etc.)any
(而不是logLevelEnum
或logLevelEnum | undefined
等)invalidStringIndex
variable in the Typescript Playground ExampleinvalidStringIndex
变量上输入 hover 时,您可以看到类型logLevelEnum[999]
= undefined
: logLevelEnum[999]
= undefined
:
string
!string
! But actually it can also be undefined
.undefined
。string|undefined
which is more accuratestring|undefined
这更准确As I understand your question据我了解你的问题
config.logLevel
is of type string
and not under your control. config.logLevel
是string
类型,不受您的控制。logLevelEnum
and everything would be easier: logLevelEnum[logLevelEnum]
is then guaranteed to be a valid enum (at compile time)logLevelEnum
并且一切都会更容易:然后保证logLevelEnum[logLevelEnum]
是一个有效的枚举(在编译时)config.logLevel
is valid, you want to use it, otherwise you want to use logLevelEnum.NOTHING
config.logLevel
有效时,你想使用它,否则你想使用logLevelEnum.NOTHING
So basically you need a function like this (which you call with config.logLevel
):所以基本上你需要一个像这样的 function(你用
config.logLevel
调用):
function getValidLogLevelEnum(logLevelName: string): logLevelEnum {
/**
* we need the correct type so that typescript will allow the index access
* note: we must cast the string to `keyof typeof logLevelEnum`
* which resolves to: "NOTHING" | "ERROR" | "WARN" | "INFO" | "DEBUG"
* i.e. all valid enum-names
*/
const enumName = logLevelName as keyof typeof logLevelEnum;
/**
* now that we have the correct type of the enum-name, we can get the enum-value
*/
const configEnum = logLevelEnum[enumName];
/**
* keep in mind, that we were cheating a little bit in the type-expression above
* We told typesript that we are sure that enumName is a valid enum-name,
* but actually it is just the value of the logLevelName string, which could be anything.
* Thus, typescript now thinks that configEnum is of type logLevelEnum, but
* actually it is `logLevelEnum | undefined` (undefined when logLevelEnum is not a valid enum-name)
*
* This is the reason why use the nullish coalescing operator (??):
* see https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#nullish-coalescing
*
* so we return configEnum, or logLevelEnum.NOTHING (when configEnum is undefined)
*/
return configEnum ?? logLevelEnum.NOTHING;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.