this 타입과 관련된 유틸리티 클래스는 apply를 통한 재정의이므로 생략
keyof 키워드
타입 값에 존재하는 모든 프로퍼티의 키값 을 union 형태로 리턴 받는다.
interface Todo {
id: number;
text: string;
due: Date;
}
type TodoKeys = keyof Todo; // "id" | "text" | "due"
TypeScript
복사
never 타입
에러가 발생하면 프로세스를 중단하지 않고 무시하는 타입. any를 제외한 모든 타입의 원시타입이다. 변수 선언은 불가능하고 함수의 리턴 타입으로 에러를 무시하고 진행시키는 역할
Partial<T>
inteface Todo {
tit: string;
desc: stirng;
}
function updateTodo(todo: Todo, fieldsToUpdate: Partial<Todo>) {
return { ...todo, ...fieldsToUpdate}
}
const todo2 = updateTodo(todo1, {
desc: 'throw out trash',
}
TypeScript
복사
Required<T>
type Required<T> = {
[P in keyof T]-?: T[P];
};
TypeScript
복사
마이너스 연산자는 옵셔널을 제거해주는 연산자입니다.
interface Props {
a?: number;
b?: string;
};
const obj: Props = { a: 5 }; // OK
const obj2: Required<Props> = { a: 5 }; //에러발생
TypeScript
복사
Readonly<T>
모든 프로퍼티를 값을 참조만 할 수 있도록 바꿉니다.
type Readonly<T> = {readonly[P in keyof T]: T[P];};
TypeScript
복사
Partial과 비슷하지만 옵셔널(=?)이 아닌 readonly 키워드를 사용합니다.
예시
interface Card {
name: string;
price: number
}
type readOnlyCard = Readonly<Card>;
let readonlyUser: readOnlyCard = {name: 'Sonata', price: 10000}
readonlyUser.price = 3 // 에러발생
TypeScript
복사
Record<K,T>
K타입을 Key값 타입으로, T타입을 밸류 값 타입으로 갖는 타입을 리턴합니다.
type Record<K extends keyof any, T> = {
[P in K]: T;
};
TypeScript
복사
타입 K와 T를 받아 타입 K를 프로퍼티 키값으로 하는 타입을 만들 수 있습니다.
주로 K에 유니온 문자열 값을 주어 map 형식의 타입을 만들 수 있고 여러 값들을 원하는 키값에 따라 분류할 때 유용합니다.
예시
export interface Car {
name: string,
price: number
}
const productList: Record<"SONATA" | "AVANTE", Car> = {
SONATA: {name: "SONATA", price: 10000},
AVANTE: {name: "SONATA", price: 10000}
}
const nextProductList: Record<string, Car> = {
SONATA: {name: "SONATA", price: 10000},
AVANTE1: {name: "SONATA", price: 10000},
AVANTE2: {name: "SONATA", price: 10000},
AVANTE3: {name: "SONATA", price: 10000},
}
TypeScript
복사
위 예제에서는 SONATA, AVANTE 두 개만을 키값만을 Union string으로 갖는 경우와 string 타입을 키값으로 갖는 경우 두 가지입니다.
응용
type memo = { content: string, date: string }
const FRIENDS_LIST = ["harry", "jason", "dukkey"] as const
type FriendTypeArray = typeof FRIENDS_LIST[number];
type friendType = Record<FriendTypeArray, memo>
TypeScript
복사
만약 Union Type이 아닌 배열의 값을 키값으로 사용하고 싶다면 위처럼 변형하여 사용할 수 있습니다.
Pick<T,K>
T 타입으로부터 K 프로퍼티만 추출합니다.
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
TypeScript
복사
키값 T에 속하는 유니온 타입 K를 받아(= K extends keyof T) 매칭 되는 프로퍼티만 리턴합니다.( = [P in K: T [P])
interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoPreview = Pick<Todo, 'title' | 'completed'>;
const todo: TodoPreview = {
title: 'Clean room',
completed: false,
};
TypeScript
복사
Exclude<T,U>
T 타입들 중 U타입들과 겹치는 타입을 제외합니다.
type Exclude<T, U> = T extends U ? never: T;
TypeScript
복사
타입 T가 타입 U를 상속하거나 동일 타입이라면 무시(never)하고 아닐 경우 타입 값을 리턴합니다.
타입 T 또는 타입 U가 유니온 타입으로 온다면 각각의 교집합이 무시(never)됩니다.
type T0 = Exclude<"a" | "b" | "c", "a">; // "b" | "c"
type T1 = Exclude<"a" | "b" | "c", "a" | "b">; // "c"
type T2 = Exclude<string | number | (() => void), Function>; // string | number
TypeScript
복사
Extract<T,U>
T타입에서 U타입과 겹치는 타입만을 가져옵니다.
type Extract<T, U> = T extends U ? T : never;
TypeScript
복사
Exclude와 거의 비슷하지만 T와 never의 위치만 다르기 때문에 교집합을 리턴합니다.
예시
type T0 = Extract<"a" | "b" | "c", "a" | "f">; // "a"
type T1 = Extract<string | number | (() => void), Function>; // () => void
TypeScript
복사
Omit<T,K>
Pick과는 정반대로 T타입으로부터 K프토퍼티를 제거합니다.
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>> // typeX propO
TypeScript
복사
Pick과 Exclude를 한 곳에 넣어놓고 보면 다소 가독성이 떨어져 이해하기 난감할 수 있는데 아래 코드를 보시면 조금 더 쉽게 이해할 수 있습니다.
type Car = {
name: string;
price: number;
brand: string;
};
// Car에 속하는 Key값들중 brand를 키값으로 갖지않는 프로퍼티들을
// RemainingKey에 넣습니다.
type RemainingKeys = Exclude<keyof Car, "brand">;
//Car에서 RemaningKeys에 속하는 키값에 속하는 프로퍼티들을 리턴합니다
type NoBrandCard = Pick<Car, RemainingKeys>;
//결과 type NoBrandCard = { name: string; age: number; };
TypeScript
복사
예시
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
interface Test {
a: string;
b: number;
c: boolean;
}
type OmitA = Omit<Test, "a">; // Equivalent to: {b: number, c: boolean}
type OmitAB = Omit<Test, "a"|"b">; // Equivalent to: {c: boolean}
TypeScript
복사
NonNullable<T>
T타입에서 null or undefinded을 제외하고 리턴합니다.
type NonNullable<T> = T extends null | undefined ? never : T;
TypeScript
복사
null 혹은 undefined 타입이거나 상속한다면 무시(never) 아니라면 타입을 리턴합니다.
예시
type T0 = NonNullable<string | number | undefined>; // string | number
type T1 = NonNullable<string[] | null | undefined>; // string[]
TypeScript
복사
Parameters<T>
함수의 파라미터를 타입으로 리턴합니다.
type Parameters<T extends (...args:any) => any> =
T extends(...args : infer P) => any? P :never;
TypeScript
복사
T는 (…args : any) => any로 선언되어 있습니다. 모든 파라미터를 인자로 받고 결괏값으로 모든 값을 리턴하기 때문에 사실상 모든 함수를 상속합니다.
infer 키워드는 타입 스크립트가 엔진이 런타임 상황에서 타입을 추론할 수 있도록 하고 그 값을 P에 할당해줍니다. 파라미터 타입을 infer P로 할당하고 함수의 형태가 참이라면 파라미터를 아니라면 무시(never)합니다.
예시
declare function f1(arg: { a: number, b: string }): void
type T0 = Parameters<() => string>; // []
type T1 = Parameters<(s: string) => void>; // [string]
type T2 = Parameters<(<T>(arg: T) => T)>; // [unknown]
type T4 = Parameters<typeof f1>; // { a: number, b: string }
type T5 = Parameters<any>; // unknown[]
// never는 any를 제외한 모든 타입의 원시타입이기때문에
// 함수타입 T에 never로 주어도 에러가 발생하지 않고
// 인자값으로도 어떠한 값이든 올 수 있기때문에 any가 리턴됩니다.
type T6 = Parameters<never>; // any
// T extends (...args: any) => any에서
// never 타입을통해 에러를 막지않았기떄문에 함수가 아니라면 에러가 발생합니다.
type T7 = Parameters<string>; // Error
type T8 = Parameters<Function>; // Error
TypeScript
복사
any와 never 모두 함수를 대신하여 파라미터 타입으로 사용할 수 있기 때문에 에러가 발생하지 않습니다.
ConstructorParameters<T>
생성자를 갖는 함수 타입의 생성자 파라미터를 리턴합니다. 함수가 아니라면 never를 리턴합니다.
type ConstructorParameters<T extends new(...args:any) => any> =
T extends new(...args : infer P) => any ? P : never;
TypeScript
복사
위의 parameters와 비슷하지만 new키워드를 추가하여 생성자 파라미터로 한정하였습니다.
예시
class Person {
private _firstname: string
private _lastname: string
constructor(firstname: string, lastname: string) {
this._firstname = firstname
this._lastname = lastname
}
}
type constructuinArgsType = ConstructorParameters<typeof Person>;
let personConstructionArgs: constructuinArgsType = ['first', 'last']
TypeScript
복사
ReturnType<T>
함수의 리턴타입을 가져옵니다.
type ReturnType<T extends(...args:any) =>any> = T extends(...args:any) =>infer R ? R :any;
TypeScript
복사
parameter와 비슷하지만 타입 추론(infer)을 함수의 결괏값에 할당한 후 리턴합니다.
예시
let f1 = () => ({ a: 23, b: 33 });
type T0 = ReturnType<() => string>; // string
type T1 = ReturnType<(s: string) => void>; // void
type T2 = ReturnType<(<T>() => T)>; // {}
type T3 = ReturnType<(<T extends U, U extends number[]>() => T)>; // number[]
type T4 = ReturnType<typeof f1>; // { a: number, b: string }
TypeScript
복사
InstanceType<T>
생성자로 초기화된 인스턴스 타입을 리턴합니다.
type InstanceType<T extends new(...args:any) =>any> = T extends new(...args:any) =>infer R ? R :any;
TypeScript
복사
타입 추론(infer)을 인스턴스 값에 할당한 후 리턴하였습니다.
예시
let funTest = () => ({ a: 23, b: 33 });
type T0 = ReturnType<() => string>; // string
type T1 = ReturnType<(s: string) => void>; // void
type T2 = ReturnType<(<T>() => T)>; // {}
type T3 = ReturnType<(<T extends U, U extends number[]>() => T)>; // number[]
type T4 = ReturnType<typeof funTest>; // { a: number, b: string }
type T5 = ReturnType<any>; // any
type T6 = ReturnType<never>; // any
TypeScript
복사
빌트인 이외의 리소스
만약 원하는 빌트인 유틸리티 클래스에서 필요한 타입을 찾을 수 없다면 utility-types 를 추천드립니다.