首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何根据枚举键(从字符串)返回多个枚举类型的类型记录枚举值?

如何根据枚举键(从字符串)返回多个枚举类型的类型记录枚举值?
EN

Stack Overflow用户
提问于 2022-06-06 12:12:07
回答 1查看 160关注 0票数 1

我有一个环境变量作为字符串输入到我的应用程序中,并构建了一个配置方法来验证并返回基于enum键的枚举值(来自string):

代码语言:javascript
复制
import { LedMatrix, RowAddressType, MuxType } from 'rpi-led-matrix'

// Validate and return valid MatrixOptions.rowAddressType
export const configRowAddressType = (
  configRowAddressType?: string,
): RowAddressType => {
  if (!configRowAddressType) {
    return LedMatrix.defaultMatrixOptions().rowAddressType
  }

  const rowAddressType = configRowAddressType as keyof typeof RowAddressType

  const keys = Object.keys(RowAddressType)
  if (keys.includes(rowAddressType)) {
    return RowAddressType[rowAddressType]
  }

  if (rowAddressType) {
    console.error(
      `supplied rowAddressType key of ${rowAddressType} is not a valid option, assigning default of ${
        LedMatrix.defaultMatrixOptions().rowAddressType
      }.`,
    )
  }

  return LedMatrix.defaultMatrixOptions().rowAddressType
}

它起作用了。但是,我有另一个看起来非常相似的方法,它验证并键入另一个变量表示另一个枚举键:

代码语言:javascript
复制
// Validate and return valid MatrixOptions.multiplexing
export const configMultiplexing = (configMultiplexing?: string): MuxType => {
  if (!configMultiplexing) {
    return LedMatrix.defaultMatrixOptions().multiplexing
  }

  const multiplexing = configMultiplexing as keyof typeof MuxType

  const keys = Object.keys(MuxType)
  if (keys.includes(multiplexing)) {
    return MuxType[multiplexing]
  }

  if (multiplexing) {
    console.error(
      `supplied multiplexing key of ${multiplexing} is not a valid option, assigning default of ${
        LedMatrix.defaultMatrixOptions().multiplexing
      }.`,
    )
  }

  return LedMatrix.defaultMatrixOptions().multiplexing
}

我将总共有五种类似的方法。这似乎是多余的,但我正在挣扎如何返回一个动态枚举类型。下面是一个可能奏效的粗略例子,也许并不理想:

代码语言:javascript
复制
export const configEnumValueByKey = (inputValue: string, enumType: RowAddressType | MuxType | SomethingElse | AnotherSomething | MoreSomething | YetAnother): RowAddressType | MuxType | SomethingElse | AnotherSomething | MoreSomething | YetAnother => {
  // ...
}

是否可以为处理动态设置返回类型的单个方法进行重构?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-06-10 03:20:08

我在做类似的事情,所以我给你做了扩展。我不知道该说什么,如果你有兴趣的话,这里有一些参考资料。功能过载 类型泛型

编辑:如果rawValue是枚举值之一,则修正返回defaultValue

代码语言:javascript
复制
//Enums
enum Locations {
    Address1 = 0,
    Address2 = 1,
    Address3 = 'SDF'
}
enum Actions {
    Scan = 0,
    Print = 1,
    SelfDestruct = 2
}

//Wrappers around the actual validate function, which can be left untouched
const configLocations = (location?: string) => {
    return validateEnum(Locations, location, Locations.Address1);
}
const configActionType = (actionType?: string) => {
    //No default value
    return validateEnum(Actions, actionType);
}

const val = configLocations('SDF'); //Will be the default value, accurate type
const val2 = configActionType('Print')
console.log(val, val2);

//Generic type for the enum list
type Enum<E> = Record<keyof E, number | string> & { [k: number]: string };
// Use overloads to correctly type return value, if `defaultValue` is present.
// Quirk: `rawValue` cannot be an optional parameter because we want to type `defaultValue` as required. Must specify undefined explicitly in some cases

function validateEnum<E extends Enum<E>>(enumList: E, rawValue: string | undefined): E[keyof E] | undefined;
function validateEnum<E extends Enum<E>>(enumList: E, rawValue: string | undefined, defaultValue: E[keyof E]): E[keyof E];
function validateEnum<E extends Enum<E>>(
    enumList: E,
    rawValue: string | undefined,
    defaultValue?: E[keyof E]
) : E[keyof E] | undefined {
    
    if (rawValue === undefined) {
        return defaultValue;
    }

    // Object.keys on an enum also returns the values (for non-string values). console.log(Object.keys(Locations)) -> ["0", "1", "Address1", "Address2", "Address3"]
    // We can just filter out the keys that are not parsable as numbers (numeric enum keys are not allowed anyways).
    const enumKeys = Object.keys(enumList).filter(k => isNaN(Number(k)) === true);
    if (enumKeys.includes(rawValue)) {
        return enumList[rawValue as keyof E];
    }

    console.error(
        `supplied rowAddressType key of ${rawValue} is not a valid option` +
        (defaultValue ? `. Replacing with a default value of: ${defaultValue}.` : '')
    );
    return defaultValue;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72517505

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档