const mayBeColor: Color | undefined = (<any>Color)["WrongInput"];
if (mayBeColor !== undefined){
// TypeScript will understand that mayBeColor is of type Color here
}
<一个href = " http://www.typescriptlang.org/play/ src = enum % 20颜色% 7 b % 0 a % 20% 20% 20% 20红色% 2 c % 20绿色% 0 a % d % 0 7 aconst % 20 % % 20 3颜色3 d % % 20% 20% 3藤% 3 ecolor % 5 b % 22绿色% 22% 5 d % 3 b % 0 aconsole.log(% 22颜色% 3 a % 20% 22% 20% 2 b % 20颜色)% 3 b % 0 a % 0 aconst % 20 maybecolor % 3 7 c % 20颜色% 20% % 20未定义的3 d % % 20% 20% 3藤% 3 ecolor % 5 b % 22 wronginput % 22% 5 d % 3 b % 0 aconsole.log(% 22非% 20现有% 20颜色% 3 a % 20% 22% 20% 2 b % 20 maybecolor) % 3 b % 0 a % 0 aconst % 20 maybecolor2 % 3 7 c % 20颜色% 20% % 20未定义的3 d % % 20% 20% 3藤% 3 ecolor % 5 b % 22绿色% 22% 5 d % 3 b % 0 aconsole.log(% 22现有% 20颜色% % 20% 22% 2 bmaybecolor2 3) % 3 b noreferrer“rel = >操场< / >
如果不将enum类型转换为<any>类型,TypeScript将显示错误:
元素隐式具有“any”类型,因为索引表达式不是类型“number”。
这意味着默认情况下,TypeScript Enum类型与数字索引一起工作。
let c = Color[0],但不是像let c = Color["string"]这样的字符串索引。这是微软团队针对更普遍的问题对象字符串索引 . .的一个已知限制
function enumFromStringValue<T> (enm: { [s: string]: T}, value: string): T | undefined {
return (Object.values(enm) as unknown as string[]).includes(value)
? value as unknown as T
: undefined;
}
enumFromStringValue(Color, "RD"); // Color.Red
enumFromStringValue(Color, "UNKNOWN"); // undefined
enumFromStringValue(Color, "Red"); // undefined
enum Color{
Red, Green
}
let typedColor: Color = Color.Green;
let typedColorString: keyof typeof Color = "Green";
// Error "Black is not assignable ..." (indexing using Color["Black"] will return undefined runtime)
typedColorString = "Black";
// Error "Type 'string' is not assignable ..." (indexing works runtime)
let letColorString = "Red";
typedColorString = letColorString;
// Works fine
typedColorString = "Red";
// Works fine
const constColorString = "Red";
typedColorString = constColorString
// Works fine (thanks @SergeyT)
let letColorString = "Red";
typedColorString = letColorString as keyof typeof Color;
typedColor = Color[typedColorString];
enum Color{
Red, Green
}
// To String
var green: string = Color[Color.Green];
// To Enum / number
var color : Color = Color[green as keyof typeof Color]; //Works with --noImplicitAny
enum Color{
Red, Green
}
// To Number
var greenNr: number = Color['Green'];
console.log(greenNr); // logs 1
// To String
var greenString: string = Color[Color['Green']]; // or Color[Color[1]
console.log(greenString); // logs Green
// In your example
// recieve as Color.green instead of the string green
var green: string = Color[Color.Green];
// obtain the enum number value which corresponds to the Color.green property
var color: Color = (<any>Color)[green];
console.log(color); // logs 1
export const stringToEnumValue = <ET, T>(enumObj: ET, str: string): T =>
(enumObj as any)[Object.keys(enumObj).filter(k => (enumObj as any)[k] === str)[0]];
enum ColorStr { Red = "red", Green = "green" }
const c5_by_name = ColorStr["Red"] // ✅ this works
const c5_by_value_error = ColorStr["red"] // ❌ , but this not
const enumFromValue = <T extends Record<string, string>>(val: string, _enum: T) => {
const enumName = (Object.keys(_enum) as Array<keyof T>).find(k => _enum[k] === val)
if (!enumName) throw Error() // here fail fast as an example
return _enum[enumName]
}
const c5 = enumFromValue("red", ColorStr)
enum Color { red, green}
// Get the keys 'red' | 'green' (but not 'parse')
type ColorKey = keyof Omit<typeof Color, 'parse'>;
namespace Color {
export function parse(colorName: ColorKey ) {
return Color[colorName];
}
}
// The key 'red' exists as an enum so no warning is given
Color.parse('red'); // == Colors.red
// Without the 'any' cast you would get a compile-time warning
// Because 'foo' is not one of the keys in the enum
Color.parse('foo' as any); // == undefined
// Creates warning:
// "Argument of type '"bar"' is not assignable to parameter of type '"red" | "green"'"
Color.parse('bar');
function parseColorName(color: string): Color {
switch (color) {
case 'Red': return Color.Red;
case 'Green': return Color.Green;
default: throw new Error('unknown color');
}
}
interface StandardEnum<T> {
[id: string]: T | string;
[nu: number]: string;
}
/**
* Converts the given representation of the value of one enumerated constant to an equivalent enumerated type.
*
* @param type - An enumeration type
* @param value - A value to convert
*/
export const genericValueToEnum = <T, K extends StandardEnum<T>> (
type: StandardEnum<T>,
value: K[keyof K]
): T | undefined => {
const keys = Object.keys(type); // ...but, not really.
const values = Object.values(type)
// Filter enum member names because `Object.values()` includes them.
.filter((value) => !(
typeof value === 'string' &&
keys.includes(value) &&
type[value] !== value
));
return values.includes(value)
? value as unknown as T
: undefined;
}
这将适用于所有枚举,无论它们多么复杂(或奇怪),只要它们没有被标记。
enum OddEnum {
None = -1,
No = 0,
Yes = 1,
Twenty = '20'
Other = 'Other',
MORE = 'More',
};
genericValueToEnum(OddEnum, -1); // => [-1] as OddEnum;
genericValueToEnum(OddEnum, 'Other'); // => ['Other'] as OddEnum;
genericValueToEnum(OddEnum, 'MORE'); // => undefined;
enum Color {
Red = "red",
Green = "green"
}
const colorsMap = new Map<string,Color>(Object.values(Color).map((v) => [v,v]))
function parseColor(volumeData: string): Color | undefined {
return colorsMap.get(volumeData)
}
const color = parseColor("red")