본문 바로가기

프론트엔드

TS - 유틸리티 타입

Partial

: 타입의 필수 값들을 모두 옵셔널 값으로 변경해준다. ⇒ 전부 옵셔널이 되기 때문에 비추

=> type P<T> = {
	[Key in keyof T]?: T[Key]
}

interface Profile {
	name: string
	age: number
	married: boolean
}

const ha0: Profile = {
	name: 'ha0',
	age: 30,
	married: false
}

// 개인정보보호 등으로 일부만 사용할 경우
const protectedHa0: Partial<Profile> = {
	name: 'ha0',
	age: 30
}

Pick, Omit

: 특정 타입에서 사용할 옵션들만 가지고 옴

=> type P<T, S extends keyof T> = {
	[Key in S]: T[Key]
}
=> type O<T, S extends keyof any> = Pick<T, Exclude<keyof T, S>>
interface Profile {
	name: string
	age: number
	married: boolean
}

const ha0: Profile = {
	name: 'ha0',
	age: 30,
	married: false
}

// 개인정보보호 등으로 일부만 사용할 경우
const protectedHa0: Pick<Profile, 'name' | 'age'> = {
	name: 'ha0',
	age: 30
}

const protectedHa0: Omit<Profile, 'married'> = {
	name: 'ha0',
	age: 30
}

Exclude, Extract

Exclude: T 타입 - U 타입

type Exclude<T, U> = T extends U ? never : T

Extract: key에서 추출

type Exclude<T, U> = T extends U ? T : never

type Animal = 'Cat' | 'Dog' | 'Human'; 
type Mammal = Exclude<Animal, 'Human'> // Cat, Dog
type Mammal = Extract<Animal, 'Cat'| 'Dog'> // Cat, Dog

type A = Exclude<keyof Profile, 'married'> // name, age

Required, Readonly

Required

다 옵셔널로 타이핑 되어 있는 것을 다 필수로 만들 때 사용

type Required<T> = {
	[Key in keyof T]-?: T[Key]
}

// -?는 modifier (옵셔널 제거)
interface Profile {
	name?: string
	age?: number
	married?: boolean
}

const ha0: Required<Profile> = {
	name: 'ha0'
	age: 30
	married: false
}

Readonly

수정 못하게 막고 싶을 때 사용

type Readonly<T> = {
	readonly [Key in keyof T]: T[Key]
}
interface Profile {
	name?: string
	age?: number
	married?: boolean
}

const ha0: Readonly<Profile> = {
	name: 'ha0'
	age: 30
	married: false
}
ha0.age = 35 // type error

Record

객체에 아무거나 넣고 싶을 때 사용

type Record<T extends keyof any, K> = {
	[Key in T]: K
}
interface Obj {
	[key: string]: number;
}

// 위에꺼랑 같음
const a: Record<string, number> = { a: 3, b: 5, c: 7 }

NonNullable

type NonNullable<T> = T extends null | undefined ? never : T
type A = string | null | undefined | boolean | number;
type B = NonNullable<A> // string | boolean | number;

infer (추론)

타입간에도 인덱스로 접근 가능하다.

infer는 extends 에서만 사용 가능하다.

추론 조건 ? 추론 성공 시의 값 : 추론 실패 시의 값

function zip(x: number, y: string, z: boolean): { x: number, y: string, z: boolean) {
	return { x, y, z }
}

type Params = Parameters<typeof zip>; // [x: number, y: string, z: boolean]
type First = Prameters[0] // number

// 매개변수를 추론하는 타입으로 만들어보면
Type P<T extends (...args: any) => any> = T extends (...args: infer A) => any ? A : never;
//1. T를 함수로 제한 
// -> 추론 값이 있으면 그걸 쓰고 없으면 never

// 리턴값 추론
Type R<T extends (...args: any) => any> = T extends (...args: any) => infer A ? A : never;

기타

Lowercase, Uppercase

const a = 'Hello World'
cosnt b: Lowercase<typeof a> // hello world