소개
유틸리티 타입은 이미 정의된 타입을 변형하여 사용할 때 사용한다.
유틸리티 타입
(Utility type)은 이미 정의되어 있는 타입 구조를 변경해서 재사용하고자 할 때 사용한다.
우선 타입스크립트 설정 파일 내 compilerOptions 속성을 체크해준다.
{
"compilerOptions": {
"lib": ["ESNext"]
}
}
정보
(TypeScript 설정 파일인 tsconfig.json에서 compilerOptions는 TypeScript 컴파일러가 코드를 컴파일할 때 사용할 설정을 정의하는 속성이다. 해당 설정을 통해 컴파일러의 동작 방식을 제어하고, 프로젝트에 맞는 맞춤형 컴파일 환경을 구성할 수 있다.)
(ESNext는 JavaScript의 최신 기능과 업데이트를 포함하는 스펙을 가리키는 용어)
1. Pick
Pick 은 이미 존재하는 특정 타입의 속성을 뽑아서 새로운 타입을 만들어 낼 때 사용된다.
Pick<타겟 타입, '타겟 타입 내 추출할 속성 이름'
Pick<타겟 타입, '타겟 타입 내 속성 이름' | '타겟 타입 내 속성 이름2'> (유니언 타입 형태로 사용 가능)
* Pick 유틸리티 타입에서 사용되는 <> 는 제네릭 문법이다.
즉, <>에서 넘겨진 타입으로 타입이 정의되는 것이다.
interface Profile {
id: string;
name: string;
address: string;
}
type ProfileId = Pick<Profile, 'id'>;
type PrifileIdName = Pick<Profile, 'id' | 'name'>;
위의 예시는 Pick 이라는 유틸리티 타입을 이용한 것이다.
Profile 인터페이스의 id 속성을 추출해서 ProfileId라는 새로운 타입으로 정의한다.
2. Omit
특정 타입에서 속성 몇 개를 제외한 나머지 속성으로 새로운 타입을 생성할 때 사용된다.
Omit<타겟 타입, '타겟 타입 내 추출할 속성 이름'
Omit<타겟 타입, '타겟 타입 내 속성 이름' | '타겟 타입 내 속성 이름2'> (유니언 타입 형태로 사용 가능)
문법 자체는 Pick과 다를바 없다.
interface UserProfile {
id: string;
name: string;
address: string;
};
type User = Omit<UserProfile, 'address'>;
//결과
type User = {
id: string;
name: string;
};
3. Partial
특정 타입의 모든 속성을 모두 옵션 속성으로 변환한 타입으로 생성해준다.
Partial<타겟 타입>
타겟이 되는 타입의 "모든 속성" 을 옵션 속성으로 변경하는 것이기 때문에 타입 이름만 넘기면 된다.
타겟 타입의 속성을 모두 Optional하게 사용 가능하므로 보통 데이터 수정 API를 다룰 때 사용하면 좋다.
interface Todo {
id: string;
title: string;
checked: boolean;
}
const updateTodo = (todo: Todo): void => {
//...
}
위와 같은 경우 title이나 checked 상태만 수정하는 것을 대처하기엔 유연하지 못할 수 있다.
const updateTodo = (todo: Partial<Todo>): void => {
//...
}
Partial 으로 대응하면 어떤 값으로 넘겨져도 처리하기 용이하다.
4. Exclude
유니언 타입을 변형한다.
Exclude<대상 유니언 타입, '제거할 타입 이름'>
Exclude<대상 유니언 타입, '제거할 타입 이름1' | '제거할 타입 이름2'>
type Languages = 'C' | 'Java' | 'TypeScript' | 'React' ;
type TrueLanguages = Exclude<Languages, 'React'>;
//info
type Languages = "C" | "Java" | "TypeScript"
물론 인자로 유니언 타입을 넘기면 다수의 타입을 수정할 수 있다.
5. Record
타입 1개를 속성의 Key로 받고 다른 타입 1개의 속성 Value을 받아 객체 타입으로 변환해 준다.
Record<객체 속성의 키로 사용할 타입, 객체 속성의 값으로 사용할 타입>
첫 번째 제네릭 타입에는 string, number, string 유니언, number 유니언 등이 들어갈 수 있고,
두 번째 제네릭 타입에는 아무 타입이나 넣을 수 있다.
실제 값을 변경하는 것이 아니라 마치 map()을 쓰는 것과 같이 변환만 해준다.
잘만 사용하면 기존의 코드의 중복된 부분을 상당수 제거 할 수 있을 것으로 보인다.
type HeroProfile = {
skill: string;
age: number;
};
type HeroNames = 'thor' | 'hulk' | 'capt';
type Heroes = Record<HeroNames, HeroProfile>;
//info
type Heros = {
thor: HeroProfile;
hulk: HeroProfile;
capt: HeroProfile;
}
Heros 타입의 형태는 객체고 키 값은 HeroNames로 이뤄져있고, 속성은 HeroProfile 타입의 형태를 취하고 있다.
Heros 타입을 이용하면 객체를 간단히 선언할 수 있게 되는 것이다.
type PhoneBook = Record<string, string>;
let familyPhones: PhoneBook = {
dad: '010-1234-1234',
mom: '010-4321-4321'
};
위와 같은 형태로도 사용할 수 있다.
6. Required
타겟 타입의 모든 속성을 필수속성으로 만든다.
Required<타겟 타입>
interface UserInfo {
name: string;
age: number;
email: string;
phone?: number;
}
const user:Required<UserInfo> = {
name: 'ironman',
age: '37',
email: 'genius@a.com',
phone: '1234-1234'
};
이때 phone 속성값이 없으면 에러가 발생한다.
7. Readonly
타겟 타입의 모든 속성을 읽기 전용으로 만들어 객체 속성을 수정하지 못하게 된다.
Readonly<타겟 타입>
const user:Readonly<UserInfo> = {
name: 'ironman',
age: 37,
email: 'genius@a.com',
phone: '1234-1234'
};
user.age = 38; // 에러 발생함 age는 readonly이므로'Typescript' 카테고리의 다른 글
| [TypeScript] module/ moduleResolution 에러 해결과 옵션 정리 (1) | 2025.09.01 |
|---|---|
| [TypeScript] TS Cheat Sheet (Type, Interface) (0) | 2025.08.19 |
| 배열 관련 메서드 (0) | 2024.10.22 |
| forEach vs for (0) | 2024.10.22 |
| Shallow Copy, Deep Copy (0) | 2024.10.08 |