타입스크립트(TypeScript)는 일반적인 타입 변환 작업을 쉽게 만들어주는 여러 유틸리티 타입(Utility Types)을 제공한다.
일반적인 타입 정의는 적응을 했지만, 조금 더 타입스크립트를 잘 활용하기 위해,
유틸리티 타입을 써보려는 김에 어떤 종류가 있는지 적어본다.
1. Partial<T>
모든 프로퍼티를 선택적으로 만든다.
interface Post {
title: string;
date: Date;
content: string;
}
function updatePost(post: Post, fieldsToUpdate: Partial<Post>) {
return { ...post, ...fieldsToUpdate };
}
const post1 = {
title: "공지사항",
date: new Date(),
content: "내일 회의가 있습니다.",
};
const post2 = updatePost(post1, {
content: "회의가 취소되었습니다.",
});
2. Readonly<T>
모든 프로퍼티를 읽기 전용으로 만든다.
interface Post {
title: string;
content: string;
}
const post: Readonly<Post> = {
title: "최종 공지",
content: "내용입니다.",
};
// post.title = "변경된 제목"; // 에러: title은 읽기 전용 프로퍼티입니다.
3. Record<K,T>
타입 T
의 프로퍼티를 가지며, 키 K
의 타입을 가진 객체 타입을 생성한다.
interface PostInfo {
title: string;
content: string;
}
type Category = "공지사항" | "자유게시판" | "Q&A";
const posts: Record<Category, PostInfo[]> = {
공지사항: [],
자유게시판: [],
Q&A: [],
};
4. Pick<T,K>
타입 T
에서 프로퍼티 K
만을 선택하여 타입을 구성한다.
interface Post {
title: string;
date: Date;
content: string;
}
type PostPreview = Pick<Post, "title" | "date">;
const preview: PostPreview = {
title: "미리보기 제목",
date: new Date(),
};
5. Omit<T,K>
타입 T
에서 모든 프로퍼티를 가지지만, K
를 제외한다.
interface Post {
title: string;
date: Date;
content: string;
}
type PostWithoutDate = Omit<Post, "date">;
const post: PostWithoutDate = {
title: "제목 없는 글",
content: "내용입니다.",
};
6. Exclude<T,U>
타입 T
에서 U
에 할당할 수 있는 모든 속성을 제외한 타입을 구성한다.
type Status = "작성중" | "게시됨" | "삭제됨";
type ActiveStatus = Exclude<Status, "삭제됨">;
// ^ = type ActiveStatus = "작성중" | "게시됨"
7. Extract<T,U>
타입 T
에서 U
에 할당할 수 있는 모든 속성을 추출하여 타입을 구성한다.
type Status = "작성중" | "게시됨" | "삭제됨";
type NonActiveStatus = Extract<Status, "삭제됨" | "게시됨">;
// ^ = type NonActiveStatus = "게시됨"
8. NonNullable<T>
타입 T
에서 null
과 undefined
를 제외한 타입을 구성한다.
type OptionalString = string | null | undefined;
type NonOptionalString = NonNullable<OptionalString>;
// ^ = type NonOptionalString = string
9. ReturnType<T>
함수 타입 T
의 반환 타입을 구한다.
type PostCreationResponse = ReturnType<() => Post>;
// ^ = type PostCreationResponse = Post
10. InstanceType<T>
생성자 함수 타입 T
의 인스턴스 타입을 구한다.
class PostClass {
title: string = "";
content: string = "";
}
type PostInstance = InstanceType<typeof PostClass>;
// ^ = type PostInstance = PostClass
사용 빈도수가 높은 유틸리티 함수
- Partial<T>: 객체를 업데이트하거나 새 객체를 생성할 때 일부 속성만을 다루고 싶을 때 자주 사용된다.
- Readonly<T>: 불변성을 강제하여 버그를 줄이는 데 도움을 준다.
- Record<K, T>: 동적인 키를 갖는 객체를 다룰 때 매우 유용합니다.
- Pick<T, K> 및 Omit<T, K>: API 응답이나 복잡한 객체에서 필요한 정보만을 추출하거나 제외해야 할 때 유용하다.
=> 유틸리티 타입들은 컴파일 타임에만 영향을 미치고 런타임 성능에는 영향을 주지 않지만,
코드의 가독성을 높이는데 아주 유용해보인다.
유틸리티 타입을 적재적소에 활용해서, 오류도 줄이고 완성도 있는 코드를 만들도록 노력해야겠다.
타입스크립트(TypeScript)는 일반적인 타입 변환 작업을 쉽게 만들어주는 여러 유틸리티 타입(Utility Types)을 제공한다.
일반적인 타입 정의는 적응을 했지만, 조금 더 타입스크립트를 잘 활용하기 위해,
유틸리티 타입을 써보려는 김에 어떤 종류가 있는지 적어본다.
1. Partial<T>
모든 프로퍼티를 선택적으로 만든다.
interface Post {
title: string;
date: Date;
content: string;
}
function updatePost(post: Post, fieldsToUpdate: Partial<Post>) {
return { ...post, ...fieldsToUpdate };
}
const post1 = {
title: "공지사항",
date: new Date(),
content: "내일 회의가 있습니다.",
};
const post2 = updatePost(post1, {
content: "회의가 취소되었습니다.",
});
2. Readonly<T>
모든 프로퍼티를 읽기 전용으로 만든다.
interface Post {
title: string;
content: string;
}
const post: Readonly<Post> = {
title: "최종 공지",
content: "내용입니다.",
};
// post.title = "변경된 제목"; // 에러: title은 읽기 전용 프로퍼티입니다.
3. Record<K,T>
타입 T
의 프로퍼티를 가지며, 키 K
의 타입을 가진 객체 타입을 생성한다.
interface PostInfo {
title: string;
content: string;
}
type Category = "공지사항" | "자유게시판" | "Q&A";
const posts: Record<Category, PostInfo[]> = {
공지사항: [],
자유게시판: [],
Q&A: [],
};
4. Pick<T,K>
타입 T
에서 프로퍼티 K
만을 선택하여 타입을 구성한다.
interface Post {
title: string;
date: Date;
content: string;
}
type PostPreview = Pick<Post, "title" | "date">;
const preview: PostPreview = {
title: "미리보기 제목",
date: new Date(),
};
5. Omit<T,K>
타입 T
에서 모든 프로퍼티를 가지지만, K
를 제외한다.
interface Post {
title: string;
date: Date;
content: string;
}
type PostWithoutDate = Omit<Post, "date">;
const post: PostWithoutDate = {
title: "제목 없는 글",
content: "내용입니다.",
};
6. Exclude<T,U>
타입 T
에서 U
에 할당할 수 있는 모든 속성을 제외한 타입을 구성한다.
type Status = "작성중" | "게시됨" | "삭제됨";
type ActiveStatus = Exclude<Status, "삭제됨">;
// ^ = type ActiveStatus = "작성중" | "게시됨"
7. Extract<T,U>
타입 T
에서 U
에 할당할 수 있는 모든 속성을 추출하여 타입을 구성한다.
type Status = "작성중" | "게시됨" | "삭제됨";
type NonActiveStatus = Extract<Status, "삭제됨" | "게시됨">;
// ^ = type NonActiveStatus = "게시됨"
8. NonNullable<T>
타입 T
에서 null
과 undefined
를 제외한 타입을 구성한다.
type OptionalString = string | null | undefined;
type NonOptionalString = NonNullable<OptionalString>;
// ^ = type NonOptionalString = string
9. ReturnType<T>
함수 타입 T
의 반환 타입을 구한다.
type PostCreationResponse = ReturnType<() => Post>;
// ^ = type PostCreationResponse = Post
10. InstanceType<T>
생성자 함수 타입 T
의 인스턴스 타입을 구한다.
class PostClass {
title: string = "";
content: string = "";
}
type PostInstance = InstanceType<typeof PostClass>;
// ^ = type PostInstance = PostClass
사용 빈도수가 높은 유틸리티 함수
- Partial<T>: 객체를 업데이트하거나 새 객체를 생성할 때 일부 속성만을 다루고 싶을 때 자주 사용된다.
- Readonly<T>: 불변성을 강제하여 버그를 줄이는 데 도움을 준다.
- Record<K, T>: 동적인 키를 갖는 객체를 다룰 때 매우 유용합니다.
- Pick<T, K> 및 Omit<T, K>: API 응답이나 복잡한 객체에서 필요한 정보만을 추출하거나 제외해야 할 때 유용하다.
=> 유틸리티 타입들은 컴파일 타임에만 영향을 미치고 런타임 성능에는 영향을 주지 않지만,
코드의 가독성을 높이는데 아주 유용해보인다.
유틸리티 타입을 적재적소에 활용해서, 오류도 줄이고 완성도 있는 코드를 만들도록 노력해야겠다.