타입스크립트 꽝꽝
[TypeScript] Java처럼 enum 사용하기
bimppap
2022. 2. 9. 10:31
문제
자바를 쓸 때 enum으로 열거형 상수를 줄곧 사용했었다.
// 추억의 로또 미션~
public enum WinningBoard {
ZERO(0, 0, ""),
FIFTH(3, 5_000, "3개 일치"),
FOURTH(4, 50_000, "4개 일치"),
THIRD(5, 1_500_000, "5개 일치"),
SECOND(5, 30_000_000, "5개 일치, 보너스 볼 일치"),
FIRST(6, 2_000_000_000, "6개 일치");
private final int hitCount;
private final int reward;
private final String message;
WinningBoard(int hitCount, int reward, String message) {
this.hitCount = hitCount;
this.reward = reward;
this.message = message;
}
}
TypeScript에서도 이처럼 enum을 쓸려고 했는데 상수처럼 쓰이질 않아서 다른 방법이 있나 찾아보게 되었다.
해결 과정
(1) TypeScript enum을 검색하자마자 제일 먼저 보이는 건 Tree-shaking을 이유로 사용하지 말라는 거였다.(;;)
그래서 Union Type을 이용해 해결하려고 했으나 아래처럼 난관에 부딪혔다.
const WinningBoard: {
[key: string]: { hitCount: number; fare: number; message: string };
} = {
ZERO: { hitCount: 0, fare: 0, message: "" },
FIFTH: { hitCount: 3, fare: 5_000, message: "3개 일치" },
FOURTH: { hitCount: 4, fare: 50_000, message: "4개 일치" },
THIRD: { hitCount: 5, fare: 1_500_000, message: "5개 일치" },
SECOND: { hitCount: 5, fare: 30_000_000, message: "5개 일치, 보너스볼 일치" },
FIRST: { hitCount: 6, fare: 200_000_000, message: "6개 일치" },
} as const;
type WinningBoard = typeof WinningBoard[keyof typeof WinningBoard];
export const findWinnings = (hits: number, bonus: boolean): WinningBoard => {
if (hits === WinningBoard.SECOND.hitCount && bonus) {
return WinningBoard.SECOND;
}
// const key = Object.keys(WinningBoard).find(k => WinningBoard[k].hitCount === hits);
// if(key === undefined) {
// return WinningBoard.ZERO;
// }
// return... 여길 어떻게 하니...
};
value의 Properties를 비교하여 맞는 값을 찾은 후, 그 값을 가진 value를 리턴하는 방식으로 구현하려고 했으나... 내가 타입스크립트에 미숙한건지 타입스크립트에 그런 기능이 없는 건지 해결할 수 없었다. 🥲 아마도 열거형은 되나 상수처럼 못 쓰니 생긴 문제 아닐까 싶다.
switch나 else if로 해결하기엔 개발자 GAO가 있었기에 머릴 싸매다가 사수한테 SOS를 쳤다.
그리고 사수 曰... "우린 백엔드라 Tree-Shaking을 걱정할 필욘 없어요."
😮...
그리고 조졸두님의 블로그글을 공유 받았다. 타입스크립트에서 자바처럼 Enum을 쓸 수 있는 오픈소스 소개 및 사용 방법 글이었다.
최종
ts-jenum 을 사용한 이후론 일사천리였다.
import { Enum, EnumType } from 'ts-jenum';
@Enum('code')
export class WinningBoard extends EnumType<WinningBoard>() {
static readonly ZERO = new WinningBoard('ZERO', 0, 0, '꽝🥲');
static readonly FIFTH = new WinningBoard('FIFTH', 3, 5_000, '3개 일치');
static readonly FOURTH = new WinningBoard('FOURTH', 4, 50_000, '4개 일치');
static readonly THIRD = new WinningBoard('THIRD', 5, 1_500_000, '5개 일치');
static readonly SECOND = new WinningBoard('SECOND', 5, 30_000_000, '5개 일치, 보너스볼 일치');
static readonly FIRST = new WinningBoard('FIRST', 6, 200_000_000, '6개 일치');
private constructor(
readonly code: string,
readonly _hitCount: number,
readonly _reward: number,
readonly _message: string,
) {
super();
}
static findWinnings = (hits: number, bonus: boolean): WinningBoard => {
if (WinningBoard.SECOND._hitCount === hits && bonus) {
return WinningBoard.SECOND;
}
const winningBoard = WinningBoard.values().find((board) => board._hitCount === hits);
if (winningBoard) {
return winningBoard;
}
return WinningBoard.ZERO;
};
}
고민이 있다면, 이렇게 타입스크립트를 자바처럼 사용해도 되나 싶긴 하다. 🤔
타입스크립트에서 자바스크립트의 장점을 살리는 방법도 공부해봐야겠다.