변수나 프로퍼티의 타입을 추론할 수 있는 연산자
let name = 'John'
let student: typeof name = 'Ace' // student: string
const name = 'John'
type Person = typeof name
const student1: Person = 'Ace' // Error ❌
const student2: Person = 'John' // student2: John
let은 기본 타입을 추론하지만 const는 값을 추론한다
객체 타입에서 객체의 키 값들을 숫자나 문자열 리터럴 유니언을 생성
type Person = {
name: string
age: number
}
type PersonModel = keyof Person // type PersonModel = keyof Person
PersonModel은 'name' | 'age'와 동일한 타입이다.
여기까지가 공식 문서에 나와 있는 내용
PersonModel을 다른 곳에서 사용할 경우 타입 확인이 불편해서 잘 안쓰일거 같다.
const person = {
name: 'john',
age: 23
}
type PersonModel = keyof typeof person // type PersonModel = "name" | "age"
이런 식으로 하면 바로 확인 가능해서 자주 사용될거 같다.
함수 Type의 반환 타입으로 구성된 타입을 생성합니다.
const fun = () => {
const val = "string"
return val
}
type Return = ReturnType<typeof fun> // type Return = string
비동기 함수에서는
const fun = async () => {
...
}
type Return = ReturnType<typeof fun> // type Return = Promise<string>
리턴 타입이 Promise로 감싸지는데 여기서
type Return = Awaited<ReturnType<typeof fun>> // type Return = string
Awaited를 사용하면 된다.
타입을 이쁘게 만들자
interface MainType {
name: string
age: number
}
type NestedType = MainType & {
isDeveloper: boolean
}
// NestedType 결과
// type NestedType = MainType & {
// isDeveloper: boolean
// }
MainType에는 뭐가 있지? 알수가 없는데...
type PrettifyType<T> = {
[K in keyof T]: T[K]
} & {}
type SubType = PrettifyType<NestedType>
// type SubType = {
// name: string;
// age: number;
// isDeveloper: boolean;
// }
이렇게 하면 감쳐줘 있던 타입들을 알수있다.
Type 집합의 모든 프로퍼티를 선택적으로 타입을 생성합니다. 이 유틸리티는 주어진 타입의 모든 하위 타입 집합을 나타내는 타입을 반환합니다.
interface Todo {
title: string;
description: string;
}
function updateTodo(todo: Todo, fieldsToUpdate: Todo) {
return { ...todo, ...fieldsToUpdate };
}
const todo1 = {
title: "organize desk",
description: "clear clutter",
};
const todo2 = updateTodo(todo1, {
description: "throw out trash", // Error ❌
});
typescript는 너 title 값 안넘겼어 확인해봐 라고 에러 발생하는데
이 문제는 fieldsToUpdate: Todo < 타입을 손보면 된다.
function updateTodo(todo: Todo, fieldsToUpdate: Partial<Todo>) {
return { ...todo, ...fieldsToUpdate };
}
Partial 추가하면
interface Todo {
title?: string;
description?: string;
}
위와 같게 된다.
그럼 반대로 옵셔널이 아닌 필수로 할때는 Required를 이용하면 된다.
const updateTodo = (todo: Todo, fieldsToUpdate: Required<Todo>) => {
...
}
Type에서 모든 프로퍼티를 선택하고 키를 제거한 타입을 생성합니다.
interface Todo {
title: string
description: string
}
const todo: Todo = {
title: 'homework',
description: 'typescript'
}
type Omiited = Omit<Todo, 'title'>
// type Omiited = {
// description: string
// }
객체 타입에서 원하는 키를 제거한다.
Omit과 비슷한 Exclude도 있다.
ExcludedUnion에 할당할 수 있는 모든 유니온 멤버를 Type에서 제외하여 타입을 생성합니다.
type Shape = {kind: 'circle'; radius: number, name: 'john'} | {kind: 'square'; x: number}
type Omitted = Exclude<Shape, {name: 'john'}>
// type Omitted = {
// kind: 'square';
// x: number;
// }
type Omitted = Exclude<Shape, {kind: 'square'}>
// type Omitted = {
// kind: 'circle';
// radius: number;
// name: 'john';
// }
유니온 타입에서 선택한 값을 가지지 않는 타입을 가진다고 생각하면 될거같다...