TypeScript에서 제공해주는 유틸리티 타입이 여러가지 있습니다.
앞으로 외부 라이브러리에서 불러오는 타입이나 import해올 수 없는 타입들을 조작하여 우리가 원하는 타입으로 변환시키는데에 유용합니다.
Partial<Type>
: Partial(파셜)은 특정 타입에 속해있는 집합을 모두 선택적으로 만드는 타입으로 변환 해줍니다.
interface IToppings {
tomato: boolean;
onion: boolean;
lettuce: boolean;
ketchup: boolean;
}
const myToppings: IToppings = {
tomato: true,
onion: true,
lettuce: true,
ketchup: true,
};
// Partial(파셜)은 특정 타입에 속해있는 집합을 모두 선택적으로 만드는 타입으로 변환
// 빈객체를 넣어도 에러가 안남
const partialToppings: Partial<IToppings> = {
onion: true,
// 모든 토핑이 있어도 되고 없어도 됩니다
// undefined로 명시해줘도 됩니다
ketchup: undefined,
};
console.log(myToppings); // { tomato: true, onion: true, lettuce: true, ketchup: true }
console.log(partialToppings); // { onion: true, ketchup: undefined }Record
Required<Type>
: Required는 Partial의 반대라고 보시면 되겠습니다. 특정 타입에 속해있는 집합을 모두 필수로 변환하는 타입입니다.
interface BubbleTeaOrder {
tea: boolean;
straw?: boolean;
}
const myBubbleTeaOrder: Required<BubbleTeaOrder> = {
tea: true,
straw: true, //없으면 error
};
Readonly<Type>
: Readonly는 유틸리티 타입 이름 그대로 한 타입의 집합을 읽기권한만 가능하게 변환해주는 타입입니다.
interface BankAccount {
accountNumber: string;
balance: bigint;
}
const myAccount: Readonly<BankAccount> = {
accountNumber: "1234",
balance: BigInt(Number.MAX_SAFE_INTEGER),
};
// 컴파일되지 않습니다
myAccount.accountNumber = "123"; // ❌ Cannot assign to 'accountNumber' because it is a read-only property.
myAccount.balance = BigInt(Number.MIN_VALUE); // ❌ Cannot assign to 'balance' because it is a read-only property.
balance의 타입을 bigint
로 써 본 이유는 JavaScript의 기본 자료형의 수는 한계점이 존재해서 Number.MAX_SAFE_INTEGER
보다 큰 수는 정확하지 않을 때가 있습니다. BigInt가 이 한계점을 해결해줍니다.
Record<Keys, Type>
: Record는 객체 타입을 설립하는데 쓰이는 유틸리티 타입입니다.
// 동일
type Type = string[];
type Type2 = Array<string>;
// 동일
type ObjectTypeRecord = Record<string, string>;
type ObjectTypeObject = { [x: string]: string };
// Record-----------------------------------------------------------------------
type Country = "Korea" | "USA" | "Canada" | "UK"; // enum으로 구현해도 됩니다
type CountryCode = 82 | 1 | 44; // enum으로 구현해도 됩니다
// 동일
type CountryToCountryCode = Record<Country, CountryCode>;
type CountryToCountryCodeObject = { [countryName in Country]: CountryCode };
const countries1: CountryToCountryCode = {
Canada: 1,
Korea: 82,
UK: 44,
USA: 1,
};
const countries2: CountryToCountryCodeObject = {
Korea: 82,
USA: 1,
Canada: 1,
UK: 44,
};
Omit<Type, Keys>
: Omit은 특정(객체) 타입에 구성되어있는 프로퍼티를 생략시킬 때 쓰는 타입입니다.
interface UserInfo {
userName: string;
favoriteColor: string;
email: string;
password: string;
}
// password 랑 email 생략
type LessUserInfo = Omit<UserInfo, "password" | "email">;
// const newUser: LessUserInfo = {
// userName: "pony",
// favoriteColor: "rainbow",
// // 생략시킨 email이 속해있어서 컴파일되지 않습니다
// email: "hello@world.hello", // ❌ Object literal may only specify known properties, and 'email' does not exist in type 'LessUserInfo'.
// };
Exclude<UnionType, ExcludedMembers>
: Exclude라는 타입은 유니언 타입에 속해있는 속성들을 생략(제거)할 때 쓰입니다.
type MyType = "dog" | "cat" | "alpaca";
type ExcludedType = Exclude<MyType, "cat" | "alpaca">;
const onlyDogAllowed: ExcludedType = "dog"; // ✅
// const noAlpaca: ExcludedType = "alpaca"; // ❌
type OnChange = (isDone: boolean) => void;
type GroupOfTypes = string | undefined | OnChange;
type FunctionType = Exclude<GroupOfTypes, string | undefined>;
const onChangeHandler: FunctionType = (isDone) => console.log(isDone); // ✅
console.log(onChangeHandler(true)); // true
// const today: FunctionType = "great day"; // ❌
Pick<Type, Keys>
: Pick타입은 한 타입의 특정 프로퍼티들만 뽑아쓸수 있도록 도와주는 타입입니다.
interface User {
firstName: string;
lastName: string;
}
interface Student {
user: User;
isGraduated: boolean;
school: string;
}
type StudentName = Pick<Student, "user" | "isGraduated">;
const studentName: StudentName = {
user: {
firstName: "winnie",
lastName: "pooh",
},
isGraduated: true,
};
Extract<Type, Union>
: Extract는 Exclude의 반대입니다. 타입에서 필요한 유니언만 뽑아오는건데 Exclude에서 썼던 예제를 다시 보겠습니다.
type MyType = "dog" | "cat" | "alpaca";
type ExtractedType = Extract<MyType, "alpaca" | "cat">;
const onlyAlpacaOrCatAllowed: ExtractedType = "cat"; // 또는 "alpaca"만 할당 가능
NonNullable<Type>
: NonNullable타입은 특정의 타입에서 null 또는 undefined타입을 생략해주는 타입입니다.
type QueryParam = string | string[] | undefined | null;
type NonNullableQueryParam = NonNullable<QueryParam>;
const queryParam: NonNullableQueryParam = "orders"; // 문자열은 허용되는 타입입니다
// const forbiddenQueryParam: NonNullableQueryParam = undefined; // 허용되지 않습니다