TypeScriptSTUDY _ 5장 . 타입 활용하기 [ 5.4 불변 객체 타입으로 활용하기 | 5.5 Record 원시 타입 키 개선하기 ]

zeroha·2024년 12월 8일
0

TypeScriptStudy

목록 보기
16/32
post-thumbnail

5.4 불변 객체 타입으로 활용하기

프로젝트 진행하면 상숫값 관리할 때 객체를 사용

컴포넌트나 함수에서 이런 객체를 사용할 때 열린 타입으로 설정 가능

열린 타입
: 추가적인 속성이나 값이 포함될 수 있는 타입을 의미해. 즉, 정의된 속성 외에 다른 속성도 허용되는 타입

함수 인자로 키를 받아서 value를 반환하는 함수를 보면...
: 키 타입을 해당 객체에 존재하는 키값으로 설정하는 것이 아니라
string으로 설정 -> getColorHex 함수의 반환 값 = any
이유) colors에 어떤 값이 추가될지 모르기 때문...

const colors {
	red : "#F45452",
    green : "#0C952A",
};

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

여기서 as const로 객체를 불변 객체로 선언하고, keyof 연산자를 사용하여 getColorHex 함수 인자로 실제 colors객체에 존재하는 키값만 받도록 설정가능.
.
.
.

1. Atom 컴포넌트에서 theme style 객체 활용하기

Atom 단위의 작은 컴포넌트( Button, Header, Input 등 )는 폰트 크기, 폰트 색상, 배경 색상 등 다양한 환경에서 우연하게 사용될 수 있도록 구현 -> props로 넘겨주도록 설정.
: 그러면 사용자가 모든 값을 인지해야 함 & 변경사항 직접 찾아서 직접 수정
-> 번거로움 , 변경에 취약한 상태

해결 : 해당 프로젝트의 스타일 값을 관리해주는 theme 객체를 두고 관리함.

theme 객체로 타입을 구체화하려면 keyof, typeof 연산자가 타입스크립트에서 어떻게 사용되는 지 알아야 함.
.
.
.

1-1) 타입스크립트 keyof 연산자로 객체의 키값을 타입으로 추출하기

타입스크립트에서 keyof 연산자는 객체 타입을 받아 해당 객체의 키값을 string 또는 number의 리터럴 유니온 타입을 반환.


1-2) 타입스크립트 typeof 연산자로 값을 타입으로 다루기

keyof 연산자는 객체 타입을 받음.
-> 객체의 키값을 타입으로 다루려면 값 객체를 타입으로 변환해야 함 : typeof 연산자 활용

타입스크립트 typeof 연산자는 단독 사용 보다는 주로 ReturnType같이 유틸리티 타입이나 keyof 연산자같이 타입을 받는 연산자와 함께 쓰임.


1-3) 객체의 타입을 활용해서 컴포넌트 구현하기

theme뿐만 아니라 여러 상숫값을 props 로 받은 다음에 객체의 키값을 추출한 타입을 활용하면 객체에 접근할 때 타입스크립트의 도움을 받아 실수 방지 가능.


5.5 Record 원시 타입 키 개선하기

객체 선언 시 키가 어떤 값인지 명확하지 않다면 Record의 키를 string이나 number 같은 원시 타입으로 명시

타입스크립트는 키가 유효 x 라도 타입상으로는 문제 x -> 오류 x
--> 이러면 런타임에 예상치 못한 에러 발생 가능
.
.
.

1. 무한한 키를 집합으로 가지는 Record

  • 음식분류 ( 한식, 일식 )를 키로 사용하는 음식 배열이 담긴 객체

Category 타입 : string
Category를 Record의 키로 사용하는 foodByCategory 객체는 무한한 키 집합을 가지게 됨.

이때 foodByCategory 객체에 없는 키값을 사용하더라도 타입스크립트는 오류 표시 x

foodByCategory["양식"]; // FoodD로 추론
foodByCategory["양식].map(food) => console.log(food.name)); // 오류가 발생하지 않는다

그러나 foodByCategory["양식"] : 런타임에서 undefined -> 오류 반환.

foodByCategory["양식"].map((food) => console.log(food.name)); // Uncaught Typearror:Cannot read properties of undefined (reading 'map')

이때 자바스크립트의 옵셔널 체이닝 등을 사용 -> 런타임 에러 방지 가능

옵셔널 체이닝 optional chaining
: 객체의 속성을 찾을 때 null 또는 undefined가 있어도 오류 없이 안전하게 접근하는 방법.

?. 문법으로 표현, 옵셔널 체이닝을 사용할 대 중간에 null 또는 undefined인 속성이 있는지 검사함.
속성 존재 -> 반환 / 속성 존재 x -> undefined 반환

foodByCategory ["양식"]?.map((food) => console.log(food.name));

그러나 어떤 값인지 undefined인지 매번 판단해야 하는 번거로움 발생
하지만 타입스크립트의 기능을 활용 -> 개발 중에 유효하지 않은 키가 사용되었는지 또는 undefined일 수 있는 값이 있는지 등을 사전 파악 가능


2. 유닛 타입으로 변경하기

키가 유한한 집합 -> 유닛 타입 ( 다른 타입으로 쪼개지지 않고 오직 하나의 정확환 값의 타입 ) 사용 가능

type Category = 한식"| "일식";

interface Food {
  name: string;
  //...
}

const foodByCategory: Record‹Category, Food[]> = {
  한식: [{ name: "제육덮밥" }, { name: "뚝배기 불고기" }], 
  일식: [{ name: "초밥" }, { name: "텐동" H1, }];// Property 'gAl' does not exist on type 'Record‹Category, Food[]>foodByCategory["양식"];

이제 Category로 -> 한식 또는 일식만 올 수 있음. -> 양식을 키로 사용하면 에러 발생
: 유닛 타입 화용 -> 개발 중에 유효하지 않은 키가 사용되었는지 확인 가능.

그러나 키가 무한해야 하는 상황에는 적합x


3. Partial을 활용하여 정확한 타입 표현하기

  • 키가 무한한 상황 : Partial 사용 -> 해당 값이 undefined일 수 있는 상태 표현 가능
  • ( 객체값이 undefined일 경우 : Partial을 사용 -> PartialRecord 타입 선언 ) -> 객체 선언할 때 활용
type PartialRecord < K extends string, T> = Partial <Record, T>>;
type Category = string;

interface Food {
  name: string;
  //...
}

const foodByCategory: PartialRecord <Category, Food[]> = {
  한식: [{ name: "제육덮밥" }, { name: "뚝배기 불고기" }], 
  일식: [{ name: "초밥" }, { name: "텐동" }],
};

foodByCategory["양식"]; // FoodD 또는 undefined 타입으로 추론
foodByCategory ["©EA|"].map (food) => console.log(food.name)); // Object is possibly'undefined'
foodByCategory["양식"]?.map((food) => console.Log(food.name)); // OK

타입스크립트 foodCategory[key]를 Food[] 또는 undefined로 추론
...이 값은 개발자에게 이 값은 undefined일 수 있으나 처리가 필요하다고 표시

-> 사전에 조치할 수 있게 되어 런타임 오류 줄일 수 있음.


도서참조 : 우아한 타입스크립트 with 리액트

profile
하 영

0개의 댓글

관련 채용 정보