我有一个环境变量作为字符串输入到我的应用程序中,并构建了一个配置方法来验证并返回基于enum键的枚举值(来自string):
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
}它起作用了。但是,我有另一个看起来非常相似的方法,它验证并键入另一个变量表示另一个枚举键:
// 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
}我将总共有五种类似的方法。这似乎是多余的,但我正在挣扎如何返回一个动态枚举类型。下面是一个可能奏效的粗略例子,也许并不理想:
export const configEnumValueByKey = (inputValue: string, enumType: RowAddressType | MuxType | SomethingElse | AnotherSomething | MoreSomething | YetAnother): RowAddressType | MuxType | SomethingElse | AnotherSomething | MoreSomething | YetAnother => {
// ...
}是否可以为处理动态设置返回类型的单个方法进行重构?
发布于 2022-06-10 03:20:08
我在做类似的事情,所以我给你做了扩展。我不知道该说什么,如果你有兴趣的话,这里有一些参考资料。功能过载 类型泛型
编辑:如果rawValue是枚举值之一,则修正返回defaultValue
//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;
}https://stackoverflow.com/questions/72517505
复制相似问题