首页 > 解决方案 > Get specific enum member from int in Typescript

问题描述

I have a specific case here where I have a React button that has a class defined by an enum, the button selects the correct class through a switch statement, testing each member of the enum. This is hardcoded and this component works fine (code below).

import * as React from 'react';
import './SquareButton.css';

export interface Props {
    buttonType: ButtonType;
    style?: object;
}

const SquareButton = ({ buttonType, style }: Props) => {

    var className = "";
    switch (buttonType) {
        case ButtonType.Hamburger:
            className = "zmdi zmdi-menu zmdi-hc-2x";
            break;
        case ButtonType.Clock:
            className = "zmdi zmdi-time zmdi-hc-2x";
            break;
        case ButtonType.Wifi:
            className = "zmdi zmdi-network-wifi zmdi-hc-2x";
            break;
        default:
            break;
    }

    return (
        <div className="squareButton" style={style} >
            <i className={className} />
        </div>
    )
}

export enum ButtonType {
    Wifi,
    Hamburger,
    Clock
}

export default SquareButton;

The issue I'm having is in testing this component, as this list of enum ButtonType is likely to grow I want to be able to loop through each button type without having to write individual tests or adding new ones each time there's a new button. Example test below.

for (var i = 0; i < Object.keys(ButtonType).length / 2; i++) {
    test(ButtonType[i] + 'square button icon class must contain zmdi', () => {
        const button = Enzyme.shallow(<SquareButton buttonType={i as ButtonType} />)
        expect(button.find('div').find('i').hasClass("zmdi")).toEqual(true);
    });
}

This successfully loops though each member in the enum but I can't figure out how to get the specific enum instance in the loop to pass to the component. Passing i as ButtonType still only passes an int value and the default in the switch is hit. I've tried lots of variations/string conversions etc but nothing I've tried works (the tests work if I hardcode an (e.g.) ButtonType.Wifi value).

How can I get a specific enum member from an integer value?

标签: reactjstypescriptenumsenzyme

解决方案


在这种情况下i,整数已经是所需的值ButtonType.Hamburger === 0,等等。

遍历枚举的问题在于枚举值不一定是数字,并且枚举键的一半是数字索引是不必要的。

enum A {
        B,
        C,
        D = 'D'
}

导致这些键:

["0", "1", "B", "C", "D"]

一个故障安全的方法是:

for (const enumKey of Object.keys(ButtonType).filter(key => isNaN(+key))) {
  const enumVal = ButtonType[enumKey] as ButtonType;

  test(`ButtonType.${enumKey} square button icon class must contain zmdi`, () => {
    const button = Enzyme.shallow(<SquareButton buttonType={enumVal} />)
    ...
  })
}

由于最好还测试特定于ButtonTypelike的类zmdi-menu,因此还应该有相应的测试,因此可能不需要带有迭代的通用测试。


推荐阅读