타입스크립트 Enum

theonde·2022년 10월 11일
post-thumbnail

JAVA에서 Enum

  • 자바에서는 Enum을 마치 객체처럼 사용할 수 있다.
public interface Calculation {
    int doCalc(int x, int y);
}

@Getter
@AllArgsConstructor
public enum Calculator {
    PLUS(Integer::sum),
    MINUS((x, y) -> x - y),
    MULTIPLY((x, y) -> x * y),
    DIVIDE((x, y) -> x / y);

    private Calculation calculation;
}
  • 위 코드 처럼 함수형 인터페이스를 이용하여 Enum값에 따라 동적인 처리가 가능하다.

  • 테스트 해보자

class CalculatorTest {

    @Test
    void calc() {
        assertThat(Calculator.PLUS.getCalculation().doCalc(5, 5)).isEqualTo(10);
        assertThat(Calculator.MINUS.getCalculation().doCalc(5, 5)).isEqualTo(0);
        assertThat(Calculator.MULTIPLY.getCalculation().doCalc(5, 5)).isEqualTo(25);
        assertThat(Calculator.DIVIDE.getCalculation().doCalc(5, 5)).isEqualTo(1);
    }
}

타입스크립트 Enum

  • 타입스크립트는 Enum타입을 열거형으로만 사용할 수 있다. (상수용)

  • 자바의 Enum처럼 특정 연산을 수행할 수 없다.

  • 그래서 static 배열을 활용해 나름대로 구현해 보았다.

export class Calculator {

  static readonly operators: Calculation[] = [
    {operator: 'plus', do: (x, y) => x + y},
    {operator: 'minus', do: (x, y) => x - y},
    {operator: 'multiply', do: (x, y) => x * y},
    {operator: 'divide', do: (x, y) => x / y},
  ]

  static find(operator: string) {
    return this.operators.filter(o => o.operator === operator).pop();
  }
}

export interface Calculation {
  operator: string;
  do: (x: number, y: number) => number;
}
  • 배열과 인터페이스를 이용하여 구현해보았다.

  • 연산자값을 받아서 해당 값에 맞는 연산을 수행한다.

  • 테스트 해보자

describe('enumTest', () => {

    it('calculator', async () => {
        expect(Calculator.find('plus').do(5, 5)).toBe(10);
        expect(Calculator.find('minus').do(5, 5)).toBe(0);
        expect(Calculator.find('multiply').do(5, 5)).toBe(25);
        expect(Calculator.find('divide').do(5, 5)).toBe(1);
    });

  • 잘 작동한다.

  • 배열을 이용한 방식은 switch문이나 if문 없이 동적인 처리가 가능하지만, enum의 장점을 제대로 누리진 못한다. (IDE 지원, 컴파일 시점 체크 등)

ts-jenum

  • ts-jenum이란 라이브러리가 있다.

  • 타입스크립트에서 Enum을 보다 다이나믹하게 사용할 수 있게 해준다. 마치 자바의 Enum 처럼.

npm install ts-jenum

  • 위 코드를 ts-jenum을 이용해서 구현해보자.
@Enum('operator')
export class ECalculator extends EnumType<ECalculator>() {

  static readonly PLUS = new ECalculator('PLUS', (x, y) => x + y);
  static readonly MINUS = new ECalculator('MINUS', (x, y) => x - y);
  static readonly MULTIPLY = new ECalculator('MULTIPLY', (x, y) => x * y);
  static readonly DIVIDE = new ECalculator('DIVIDE', (x, y) => x / y);

  private constructor(readonly operator: string, readonly calculation: (x: number, y: number) => number) {
    super();
  }

  calc(operator: string, x: number, y: number) {
    return ECalculator.values().filter(e => e.operator === operator).pop().calculation(x, y);
  }
}
  • EnumType을 상속 받는다.

  • @Enum('key')는 괄호안에 값이 해당 Enum값의 키 값이 된다.

  • 위 코드에서는 연산자를 key값으로 지정하고, 람다로 계산을 하는 함수를 구현했다.

  • 테스트 해보자.

describe('enumTest', () => {

    it('Ecalculation', async () => {
        expect(ECalculator.PLUS.calculation(5, 5)).toBe(10);
        expect(ECalculator.MINUS.calculation(5, 5)).toBe(0);
        expect(ECalculator.MULTIPLY.calculation(5, 5)).toBe(25);
        expect(ECalculator.DIVIDE.calculation(5, 5)).toBe(1);
    });

    it('Ecalc', async () => {
        expect(ECalculator.PLUS.calc('PLUS', 5, 5)).toBe(10);
        expect(ECalculator.MINUS.calc('MINUS', 5, 5)).toBe(0);
        expect(ECalculator.MULTIPLY.calc('MULTIPLY', 5, 5)).toBe(25);
        expect(ECalculator.DIVIDE.calc('DIVIDE', 5, 5)).toBe(1);
    });
});
  • Enum값의 calculation을 호출하여 계산하는 테스트와, Enum값의 key(연산자)값을 받아서 해당 Enum값을 찾은 후 계산을 수행하는 calc라는 함수를 사용하는 테스트 총 두가지 테스트를 해보았다.

  • 잘 작동한다.

  • Enum을 적극적으로 사용하고 싶다면 ts-jenum을 사용해보자.

profile
개발자ㅋ.ㅋ

0개의 댓글