React

220313 TS 유틸리티 클래스 파헤치기 읽기

Asset Type
File Type
When to use
Reference
Created by
Last edited time
2022/03/13 16:07
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
piotrwitek
만약 원하는 빌트인 유틸리티 클래스에서 필요한 타입을 찾을 수 없다면 utility-types 를 추천드립니다.