My Boundary As Much As I Experienced

타입스크립트로 constant 객체를 효과적으로 관리하는 방법 본문

FrontEnd/TypeScript

타입스크립트로 constant 객체를 효과적으로 관리하는 방법

Bumang 2024. 6. 18. 18:43

constant객체를 효과적으로 관리하는 방법

타입스크립트로 상수 객체를 관리하다보면, 이에 대응하는 타입들이 필요할 때가 있다.

 

특히 대괄호 접근자 'obj[key]' 형식으로 접근할 때 key가 그냥 string타입이면

'string은 KEY1 | KEY2 | KEY3 | ...에 할당할 수 없다'라는 식의

융통성 없는 에러 때문에 애먹은 적이 다들 있을 것이다.

 

옛날에 타입스크립트를 처음 쓸 때는 위 에러를 어떻게 고칠지 몰라 아래처럼 key들을 따로 타입화하여 해결하려했다.

그러나 아래 코드는 최선이 아니다. 왜냐하면 CONSTOBJ에 다른 속성이 추가되면

ConstObjType과 CONSTOBJ_KEY에도 일일이 한 번 씩 더 써줘야한다는 번거로움이 있기 때문이다.

// 초보의 타입스크립트 사용법

interface ConstObjType {
    a: string;
    b: string;
    c: string;
}

export const CONSTOBJ: ConstObjType = {
    a: "...",
    b: "...",
    c: "..."
}


export type CONSTOBJ_KEY = "a" | "b" | "c"

 

 

CONSTOBJ를 한 번만 수정해도 CONSTOBJ의 타입과 모든 KEY와 VALUE들이

자동으로 바뀌면 얼마나 좋을까? 이를 고민하다가 내가 정착한 타입관리법에 대해 적어보겠다.

 

나의 상수 객체 관리법

 

일단 as const로 객체를 생성한다. 타입지정을 따로해주진 않는다.

(예시로 Error 타입 객체를 사용하겠다.)

export const ERROR = {
  NUMBER: {
    0: "",
    1: "Only numbers can be entered",
    2: "You cannot enter more points than you have",
    3: "Please Enter the amount of points you wish to exchange",
  },
  STRING: {
    0: "",
    3: "Please Enter Your Wallet ID",
  },
} as const;

 

 

그리고 객체를 이용하여

전체 타입인 ERROR_TYPE를 만들어주고

키들의 유니온타입인 ERROR_KEY와

값들의 유니온타입은 ERROR_VALUE를 만들어준다.

 

('keyof typeof'의 활용이나 'typeof OBJ[KEYS]'의 활용에 대한 구체적인 설명은 생략한다.)

export type ERROR_TYPE = typeof ERROR; // ERROR객체의 타입
export type ERROR_KEY = keyof typeof ERROR; // "KEY" | "NUMBER"
export type ERROR_VALUE = typeof ERROR[ERROR_key]// "only numbers..." | "에러 어쩌고..."

 

 

그리고 객체 내의 또 다른 객체가 있다면 어떻게 이에 대한 타입을 가져올까?

예를 들어 Error의 Number 객체나 STRING 객체에 대해서는 타입지정을 어떻게 하나?

난 이에 대해서도 key와 value를 뽑아내고 싶어서 아래와 같은 코드를 짰다. 

export type NUMBER_KEY = keyof typeof ERROR["NUMBER"];
export type NUMBER_VALUE = typeof ERROR["NUMBER"][NUMBER_KEY];
export type STRING_KEY = keyof typeof ERROR["STRING"];
export type STRING_VALUE = typeof ERROR["STRING"][STRING_KEY];

 

 

 

 

전체 코드

export const ERROR = {
  NUMBER: {
    0: "",
    1: "Only numbers can be entered",
    2: "You cannot enter more points than you have",
    3: "Please Enter the amount of points you wish to exchange",
  },
  STRING: {
    0: "",
    3: "Please Enter Your Wallet ID",
  },
} as const;

export type ERROR_KEY = keyof typeof ERROR;
export type ERROR_TYPE = typeof ERROR;
export type ERROR_VALUE = typeof ERROR[ERROR_KEY]

export type NUMBER_KEY = keyof typeof ERROR["NUMBER"];
export type NUMBER_VALUE = typeof ERROR["NUMBER"][NUMBER_KEY];

export type STRING_KEY = keyof typeof ERROR["STRING"];
export type STRING_VALUE = typeof ERROR["STRING"][STRING_KEY];