[TS] Object.entries()의 key 타입 정의하기

0
post-thumbnail

발단

사용자의 OS환경을 가져와서 화면 분기를하는 작업을 진행중이었습니다.

const platforms = {
    WINDOWS: 'Win',
    MAC: 'Mac',
    IOS: 'IPhone|iPad|iPod',
    ANDROID: 'Android',
    LINUX: 'Linux',
} as const;

다음과 같이 platforms 객체를 생성해
정규표현식으로 사용자의 OS를 알아내는 함수를 작성하였습니다.

해당 함수는 platforms의 key값 또는 'UNKNOWN'을 리턴합니다.

export const getUserOS = () => {
    const userAgent = navigator.userAgent.toString();

    for (const [os, keyword] of Object.entries(platforms)) {
        const regex = new RegExp(keyword, 'i');
        if (regex.test(userAgent)) {
            return os;
        }
    }

    return 'UNKNOWN';
};

문제점

platforms를 as const로 타입을 단언해주었음에도 불구하고
typescript가 entries로 분리한 key값의 타입을 추론해주지 못하고 있었습니다.

따라서 다른 팀원이 이 함수가
key값 또는 'UNKNOWN'을 리턴하는 것을 알기 위해서는
한번 코드를 읽어봐야하는 문제가 생깁니다.

원인

typescript는 Object.keys, Object.entries의 key를 무조건 string으로 반환합니다.
string literal이 아니기때문에, 사용자는 object를 보기 전까지, key값을 알 수 없습니다.

해결책

type Entries<T> = {
    [K in keyof T]: [K, T[K]];
}[keyof T][];

T라는 오브젝트의 모든 key,value가 담긴 array 타입 Entires를 선언해줍니다.

for (const [os, keyword] of Object.entries(platforms) as Entries<typeof platforms>)

Entries<typeof platforms>를 entries에 type assertion하여

결과적으로 타입스크립트가 리턴하는 key값 타입을 추론할 수 있게끔 하였습니다.

이제 다른 팀원들이 해당 함수를 사용할때
자동완성기능을 통해 리턴타입을 쉽게 알수 있게 되었습니다...!

0개의 댓글

관련 채용 정보