[typescript] Record를 사용하여 객체 Key 타입 설정하기 🍎

객체의 타입을 설정할 때 있었던 일이다.

 

const winner = {
    "One": false,
    "Two": false,
    "Three": true,
};

 

이런 객체가 있다고 가정해보자.

 

객체의 Key값은 One, Two, Three만 될 수 있기에, 타입으로 제한해보자 👻

 

가장 처음 떠올릴 수 있는 방법은 다음과 같다!

 

type KeyExample = "One" | "Two" | "Three";

const winnerFail: { [key: KeyExample]: boolean } = {
    "One": false,
    "Two": false,
    "Three": true,
}

 

이렇게 하면 될 것 같지만!

 

타입스크립트 플레이그라운드 (타입스크립트 버전은 보시다시피 V5.6.3)

에러가 발생한다.

 

타입 에러에 따르면, 인덱스 시그니쳐 파라미터 타입은 literal 타입이나 generic 타입이 될 수 없다....

 

때문에 위와 같이 타입핑을 하려면 다음과 같이 해야한다.

 

const winnerFail: { [key: string]: boolean } = {
    "One": false,
    "Two": false,
    "Three": true,
}

 

하지만, 이 경우 원래 의도처럼 Key의 타입핑을 하는 건 아니게 된다 😭

 

그렇다면, 어떻게 이 경우 타입핑을 잘 할 수 있을까???

 

바로, Record를 사용하면 된다 ! 🎶

 

type KeyExample = "One" | "Two" | "Three";

const winnerSuccess: Record<KeyExample, boolean> = {
    "One": false,
    "Two": false,
    "Three": true,
}

 

Record를 사용하여 다음과 같이 작성하면,

 

원하던대로 객체 key값을 제한할 수 있다 👍👍👍

 

+ 24.11.14) 나중에 생각해보니, in 키워드를 사용하면 최초의 작성한 코드와 유사하지만, 동작하는 코드를 만들 수 있다.

Record 유틸리티 타입을 사용해야 겠다!는 생각탓에 in에 대해서 생각하지 못한 듯 하다...

 

in을 사용하면, Union을 순회하여 모든 경우에 대한 객체 프로퍼티 타입 설정이 가능하다.

type KeyExample = "One" | "Two" | "Three";

const winnerFail: { [key in KeyExample]: boolean } = {
    "One": false,
    "Two": false,
    "Three": true,
}

 

Record와 in 키워드를 사용하는 두 방법은 취향차이가 아닐까?

개인적으로는 in 키워드가 더 직관적인 것 같아 좋다.