TypeScript는 JavaScript의 상위 집합으로 개발 초기 오류 발견, 코드 대한 이해, 그리고 빠른 유지 보수가 가능한 코드 베이스 생성을 가능하게 하는 정적 타입을 제공한다.
TypeScript의 강력한 기능 중 하나로 유틸리티 타입이 있다. 유틸리티 타입을 통해 개발자는 기존 타입을 기반으로 새로운 타입을 생성할 수 있어, 타입 정의에서 유연성과 재사용성을 제공 할 수 있다.
유틸리티 타입으로 Pick
, Omit
, Record
, Partial
, Readonly
, Required
, Exclude
, Extract
, NonNullable
을 알아보자.
Pick
기존 타입에서 특정 프로퍼티를 선택하여 새로운 타입을 생성할 수 있다. 이는 기존 인터페이스나 타입의 부분 집합을 생성하고자 할 때 유용하다.
interface Person {
name: string;
age: number;
address: string;
}
type NameAndAddress = Pick<Person, 'name' | 'address'>;
Omit
기존 타입에서 특정 프로퍼티를 생략하여 새로운 타입을 생성 한다. 이는 특정 프로퍼티를 기존 인터페이스나 타입에서 제외하고자 할 때 유용하다.
interface Person {
name: string;
age: number;
address: string;
}
type NameAndAge = Omit<Person, 'address'>;
Record
인스턴스의 지정된 프로퍼티 키와 지정된 프로퍼티 값이 있는 객체 타입을 생성하는 데 사용된다.
type ThreeNumberProps = Record<'one' | 'two' | 'three', number>;
Patial
타입의 모든 프로퍼티를 선택적으로 만든다. 이는 부분 객체를 허용하는 타입을 생성하고자 할 때, 특히 함수 파라미터로 객체를 부분적으로 받을때 유용하다.
interface Person {
name: string;
age: number;
}
type OptionalPerson = Partial<Person>;
Readonly
모든 프로퍼티를 읽기 전용으로 만든다. 이는 객체의 프로퍼티를 생성 하고 수정되지 않도록 할 때 유용하다.
interface Person {
name: string;
age: number;
}
type ImmutablePerson = Readonly<Person>;
// Example
const person: ImmutablePerson = { ..., age: 20}
person.age = 30;
Cannot assign to 'age' because it is a read-only property.
Required
모든 프로퍼티를 필수로 만든다. 이는 객체의 모든 프로퍼티가 제공되어야 함을 보장하고자 할 때 유용하다.
interface Person {
name?: string;
age?: number;
}
type MandatoryPerson = Required<Person>;
Exclude
두 번째 타입에 할당된 타입을 첫 번째 타입에서 제외하여 타입을 생성한다. 이는 특정 리터럴 타입을 유니온 타입에서 제외하고자 할 때 유용하다.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; x: number };
type SquareShape = Exclude<Shape, { kind: "circle" }>
Extract
두 번째 타입에 할당된 타입을 첫 번째 타입에서 추출하여 타입을 생성한다. 이는 특정 리터럴 타입을 유니온 타입에서 추출하고자 할 때 유용하다.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; x: number };
type CircleShape = Extract<Shape, { kind: "circle" }>
NonNullable
null
과 undefined
를 타입에서 제외한다. 이는 타입이 null
이나 undefined
를 포함하지 않도록 보장하고자 할 때 유용하다.
type Names = string[] | null | undefined;
type NonNullableNames = NonNullable<Names>;
TypeScript 유틸리티 타입은 기존 타입을 기반으로 유연하고 재사용 가능한 타입 정의를 생성할 수 있게 해주는 유용한 기능 들이다. 이러한 유틸리티 타입을 이해하고 활용함으로써, 좀 더 견고하고 유지보수가 가능한 코드를 작성할 수 있겠다.