Study
5. 타입 활용하기
5.1 조건부 타입
조건부 타입을 활용하면 중복되는 타입 코드를 제거하고 상황에 따라 적절한 타입을 얻을 수 있기 때문에 더욱 정확한 타입 추론을 할 수 있게 된다.
5.1.1 extends와 제네릭을 활용한 조건부 타입
extends 키워드는 타입스크립트에서 다양한 상황에서 활용된다.
타입을 확장할 때와 타입을 조건부로 설정할 때 사용되며, 제네릭 타입에서는 한정자 역할로도 사용된다.
T extends U ? X : Y
조건부 타입에서 extends를 사용할 때는 자바스크립트 삼항 연산자와 함께 쓴다. 이 표현은 타입 T를 U에 할당할 수 있으면 X 타입, 아니면 Y 타입으로 결정됨을 의미한다.
5.1.2 조건부 타입을 사용하지 않았을 때의 문제점
인자로 넣는 타입에 알맞은 타입을 반환하고 싶지만, 타입 설정이 유니온으로만 되어있는 경우 타입스크립트는 해당 타입에 맞는 Data 타입을 추론할 수 없다.
인자에 따라 반환되는 타입을 다르게 설정하고 싶다면 extends를 사용한 조건부 타입을 활용하면 된다.
5.1.3 extends 조건부 타입을 활용하여 개선하기
extends 활용 예시는 크게 다음과 같이 정리할 수 있다.
- 제네릭과 extends를 함께 사용해 제네릭으로 받는 타입을 제한했다. 따라서 개발자는 잘못된 값을 넘길 수 없기 때문에 휴먼 에러를 방지할 수 있다.
- extends를 활용해 조건부 타입을 설정했다. 조건부 타입을 사용해서 반환 값을 사용자가 원하는 값으로 구체화할 수 있었다. 이에 따라 불필요한 타입 가드, 타입 단언 등을 방지할 수 있다.
5.1.4 infer를 활용해서 타입 추론하기
extends를 사용할 때 infer 키워드를 사용할 수 있다. infer는 추론하다라는 의미를 지니고 있는데 타입스크립트에서도 단어 의미처럼 타입을 추론하는 역할을 한다. 삼항 연산자를 사용한 조건문의 형태를 가지는데, extends로 조건을 서술하고 infer로 타입을 추론하는 방식을 취한다.
5.2 템플릿 리터럴 타입 활용하기
타입스크립트에서는 유니온 타입을 사용하여 변수 타입을 특정 문자열로 지정할 수 있다. 타입스크립트 4.1부터 이를 확장하는 템플릿 리터럴 타입을 지원하기 시작했다. 템플릿 리터럴 타입은 자바스크립트의 템플릿 리터럴 문법을 사용해 특정 문자열에 대한 타입을 선언할 수 있는 기능이다.
5.3 커스텀 유틸리티 타입 활용하기
타입스크립트로 프로젝트를 진행하다 표현하기 힘든 타입을 마주하게 된다면 유틸리티 타입을 활용한 커스텀 유틸리티 타입을 제작해서 사용하면 된다.
5.3.1 유틸리티 함수를 활용해 styled-components의 중복 타입 선언 피하기
StyledProps를 따로 정의하려면 Props와 똑같은 타입임에도 새로 작성해야 하므로 불가피하게 중복된 코드가 생긴다. 그리고 Props의 height, color, isFull 타입이 변경되면 StyledProps도 같이 변경돼야 한다. 이런 문제를 Pick, Omit 같은 유틸리티 타입으로 개선할 수 있다.
5.3.2 PickOne 유틸리티 함수
타입스크립트에는 서로 다른 2개 이상의 객체를 유니온 타입으로 받을 때 타입 검사가 제대로 진행되지 않는 이슈가 있다. 이런 문제를 해결하기 위해 PickOne이라는 이름의 유틸리티 함수를 사용한다.
PickOne
커스텀 유틸리티 타입 구현하기
{account: string; card?: undefined} | {account?: undefined; card: string}
이를 커스텀 유틸리티 타입으로 구현해보면 아래와 같다.
type PickOne<T> = {
[P in keyof T]: Record<P, T[P]> & Partial<Record<Exclude<Keyof T, P>, undefined>>;
}[keyof T];
5.3.3 NonNullable 타입 검사 함수를 사용하여 간편하게 타입 가드하기
타입 가드는 타입스크립트에서 많이 사용된다. 특히 null을 가질 수 있는 값의 null 처리는 자주 사용되는 타입 가드 패턴의 하나이다.
- NonNullable 타입이란
- 타입스크립트에서 제공하는 유틸리티 타입으로 제네릭으로 받는 T가 null 또는 undefined일 때 never 또는 T를 반환하는 타입이다. NonNullable을 사용하면 null이나 undefined가 아닌 경우를 제외할 수 있다.
type NonNullable<T> = T extends null | undefined ? never : T;
5.4 불변 객체 타입으로 활용하기
5.4.1 Atom 컴포넌트에서 theme style 객체 활용하기
Atom 컴포넌트에서는 theme 객체의 색상, 폰트 사이즈의 키값을 props로 받은 위 theme 객체에서 값을 받아오도록 설계한다.
5.5 Record 원시 타입 키 개선하기
객체 선언 시 키가 어떤 값인지 명확하지 않다면 Record의 키를 srting이나 number 같은 원시 타입으로 명시하곤 한다. 이때 타입스크립트는 키가 유효하지 않더라도 타입상으로는 문제없기 때문에 오류를 표시하지 않는다.