Skip to content

Latest commit

 

History

History
194 lines (142 loc) · 3.69 KB

File metadata and controls

194 lines (142 loc) · 3.69 KB

3. 맵드 타입

맵드 타입

기존의 객체 타입을 기반으로 새로운 객체 타입을 만드는 타입 조작 기능

유저 정보를 관리하는 간단한 프로그램의 일부분을 만든다고 가정.


먼저 유저 객체 타입을 정의함

interface User {
  id: number;
  name: string;
  age: number;
}

다음으로는 유저 정보가 서버에 저장되어 있다고 가정하고, 한 명의 유저 정보를 불러오는 기능을 함수로 만듬

interface User {
  id: number;
  name: string;
  age: number;
}

function fetchUser(): User {
  return {
    id: 1,
    name: "이정환",
    age: 27,
  };
}

그리고 한 명의 유저 정보를 수정하는 기능도 만들어 줌. 실제로 서버가 존재하는 것은 아니니 함수 내부는 구현했다고 하고 주석으로 비워둠

interface User {
  id: number;
  name: string;
  age: number;
}

function fetchUser(): User {
  (...)
}

function updateUser(user: User) {
  // ... 유저 정보 수정 기능
}

→ updateUser함수는 수정된 유저 객체를 받아 유저 정보를 수정함


따라서 유저 정보를 수정하려면 다음과 같이 이 함수를 호출하고 여러 개의 정보 중 수정하고 싶은 프로퍼티만 전달해 주면 됨

interface User {
  id: number;
  name: string;
  age: number;
}

function fetchUser(): User {
  (...)
}

function updateUser(user: User) {
  // ... 유저 정보 수정 기능
}

updateUser({ // ❌
  age: 25
});

그런데 updateUser 함수의 매개변수 타입이 User 타입으로 되어 있어서 수정하고 싶은 프로퍼티만 골라서 보낼 수 없는 상황임

따라서 어쩔 수 없이 다음과 같이 새로운 타입을 만들어줘야 함

interface User {
  id: number;
  name: string;
  age: number;
}

type PartialUser = {
  id?: number;
  name?: string;
  age?: number;
}

(...)

function updateUser(user: PartialUser) {
  // ... 유저 정보 수정 기능
}

updateUser({ // ✅
  age: 25
});

그럼 이제 수정하길 원하는 프로퍼티만 전달할 수 있도록 기능을 수정함

그런데 User 타입과 PartialUsre 타입이 지금 서로 중복된 프로퍼티를 정의하고 있음. 중복은 언제나 좋지 않음. 따라서 이럴 때 맵드 타입을 이용하면 됨

interface User {
  id: number;
  name: string;
  age: number;
}

type PartialUser = {
  [key in "id" | "name" | "age"]?: User[key];
};

(...)

문법을 보면.

[key in "id" | "name" | "age"]는 이 객체 타입은 key가 한 번은 id, 한 번은 name, 한 번은 age가 된다는 뜻. 따라서 다음과 같이 3개의 프로퍼티를 갖는 객체 타입으로 정의됨

  • key가 “id”일 때 → id : User[id] → id: number
  • key가 “name”일 때 → name: User[user] → name: string
  • key가 “age”일 때 → age: User[age] → age:number
{
  id?: number;
  name?: string;
  age?: number;
}

이렇게 맵드 타입을 이용하면 간단한 한줄의 코드 만으로 중복 없이 기존 타입을 변환할 수 있음

여기서 이전 시간에 배운 keyof 연산자를 이용해 한 번 더 업그레이드 하면 다음과 같음

interface User {
  id: number;
  name: string;
  age: number;
}

type PartialUser = {
  [key in keyof User]?: User[key];
};

(...)

마지막으로 맵드 타입을 이용해 모든 프로퍼티가 읽기 전용 프로퍼티가 된 타입을 만들면 다음과 같음

interface User {
  id: number;
  name: string;
  age: number;
}

type PartialUser = {
  [key in keyof User]?: User[key];
};

type ReadonlyUser = {
  readonly [key in keyof User]: User[key];
};

(...)