StudyForYou / ouahhan-typescript-with-react

우아한 타입스크립트 with 리액트 스터디 레포 🧵
4 stars 0 forks source link

#20 [5장_4] 상숫값을 불변 객체로 관리하는 방법을 알려주세요! #32

Closed hyeyoonS closed 2 months ago

hyeyoonS commented 2 months ago

❓문제

프로젝트를 진행하면서 상숫값을 관리할 때 흔히 객체를 사용합니다. 아래 코드에서 getColorHex의 반환 값은 any가 되는데요, 이를 불변 객체로 개선하는 방법을 알려주세요!

const colors = {
    red: "#F45452",
    green: "#0C952A",
    blue: "#1A7CFF",
};

const getColorHex = (key: string) => colors[key];

🎯답변

🤔객체를 열린 타입으로 설정했을 때의 문제점

🧐개선 방법

1. as const로 객체를 불변 객체로 선언하기 = 아래 'readonly' 로 타입이 바뀐다!

const colors = {
    red: "#F45452",
    green: "#0C952A",
    blue: "#1A7CFF",
} as const;

const getColorHex = (key: keyof typeof colors) => colors[key];

2. interfacereadonly로 객체를 불변 객체로 선언하기

interface Colors {
    readonly red: string;
    readonly green: string;
    readonly blue: string;
}

const colors: Colors = {
    red: "#F45452",
    green: "#0C952A",
    blue: "#1A7CFF",
};

const getColorHex = (key: keyof Colors) => colors[key];

3. keyof 연산자로 함수 인자를 colors 객체에 존재하는 키 값만 받도록 설정하기

const colors = {
    red: "#F45452",
    green: "#0C952A",
    blue: "#1A7CFF",
};

type Colors = typeof colors; ////'red' | 'green' | 'blue'

const getColorHex = (key: keyof Colors) => colors[key];

//위의 두 줄의 코드는 아래의 코드와 동일합니다. 
// const getColorHex = (key: keyof typeof colors) => colors[key];

불변 객체로 선언하면 객체 타입을 더 정확하고 안전하게 설정할 수 있습니다.

drizzle96 commented 2 months ago

우선 getColorHex의 key 인자에 colors의 키 값만 올 수 있도록 수정합니다. keyof typeof 연산자를 사용할 수 있습니다.

const colors = {
  red: '#F45452',
  green: '#0C952A',
  blue: '#1A7CFF',
}

const getColorHex = (key: keyof typeof colors) => colors[key]

이제 key 인자에 올 수 있는 값이 'red' | 'green' | 'blue'로 제한됩니다. 하지만 아직 getColorHex의 반환 타입은 string 입니다. 객체의 속성 값이 바뀔 수 있는 여지가 있어 속성 값의 타입이 string이기 때문입니다.

이 때 as const를 통해 colors를 불변 객체로 만들 수 있습니다.

const colors = {
  red: '#F45452',
  green: '#0C952A',
  blue: '#1A7CFF',
} as const

const getColorHex = (key: keyof typeof colors) => colors[key]

모든 속성은 readonly가 되므로 속성 값의 타입과 getColorHex의 반환 타입이 리터럴 타입이 됩니다. 이를 통해 타입을 더 정확하게 만들 수 있습니다.

qooktree1 commented 2 months ago
const colors = {
    red: "#F45452",
    green: "#0C952A",
    blue: "#1A7CFF",
} as const;

type ColorTypes = keyof typeof colors;

const getColorHex = (key: ColorTypes) => colors[key];
console.log(getColorHex('red'))