TypeScript 배우기6

Parker.Park·2022년 8월 5일
0

TypeScript

목록 보기
6/8

타입스크립트 시작하기, Inflearn


mapped type

mapped type은 특정 타입에 대하여 일괄적으로 적용하기 편하게 만든 기능이다. 반복작업을 피하면서 기존 타입으로 일괄적으로 속성을 바꿔 주기위한 일종의 함수같은것으로 이해하였다. mapped type은 기존 index signatures에 기반으로 프로퍼티의 타입을 선언하는 것으로 발전하였다. 기본문법은 다음과 같다.

type T1 = { [K in "p1" | "p2"]: number };

const ti: T1 = {
  p1: 3,
  p2: 10,
  p3: true // error 발생!
};

mapped type은 타입을 생성하기 위해 "[]"안에 "p1", "p2" 같은 유니온 타입들의 key값을 순회하는 제네릭 타입이라고 볼 수 있다. "K"는 식별자일뿐이다. 다음 예시를 보며 이해해보자.

interface Animal {
  name: string;
  age: number;
}

type T1<T> = { [K in keyof T]: boolean };

const animalMap: T1<Animal> = {
  name: true,
  age: false,
};

Readonly, Partial

"animalMap"객체에서 interface Animal은 제네릭으로 T1타입에서 <T>를 의미할 것이다. type T1을 보면 Animal에 있는 key값들(name, age)를 boolean으로 타입을 선언한 것이다.
mapped type기능을 사용하여 readonly와 선택 속성('?')을 적용할 수 있다. 예시를 보자.

interface Animal {
  name: string;
  age: number;
}

type T1<T> = { readonly [K in keyof T]: T[K] };
type T2<T> = { [K in keyof T]?: T[K] };

type A1 = T1<Animal>;
type A2 = T2<Animal>;

위 예시에서 T1에 들어오는 타입에 대해서 기존 속성 타입을 유지하되(T[k] 를 활용하여) readonly속석을 부여하였다. 그리고 T2는 모든 키값에 선택속성을 부여하였다.

타입T1 readonly가 적용된 A1 타입이다. 타입T2 선택속성이 적용된 A2 타입이다.

위 예시로 나온 타입은 기본적으로 TypeScript에서 Readonly, Partial 타입으로 제공하는 것이다.

type A3 = Readonly<Animal>;
type A4 = Partial<Animal>;

Pick

Readonly와 Partial과 비슷한 예로 Pick 타입에 대해 알아보자.

interface Animal {
  name: string;
  age: number;
  kind: string
}

type T1<T, K extends keyof T> = { [P in K]: T[P] };

type A1 = T1<Animal, "name" | "kind">

여기서는 제네릭이 T, K 2개가 사용 되었다. "keyof T"는 T의 속성들을 의미하고, K가 T에 할당 가능한 속성들을 의미하기 때문에, 속성들 중 고르는 것을 의미 할 것이다.(3가지 속성 모두를 골라도 될것이다.) 여기서 A1타입은 Animal 타입에서 "age"속성을 제외한 타입일 것이다. 이 맵드 타입 또한 TypeScript에서 제공하는 Pick 타입이다.

type A2 = Pick<Animal, "name" | "kind">;

Record

이번에는 Record타입에 대해 알아보자. 예시를 먼저 보도록 하자.

interface Animal {
  name: string;
  age: number;
  kind: string;
}

type T1<K extends string, T> = { [P in K]: T };

type A1 = T1<"p1" | "p2", Animal>;

type A2 = T1<"p1" | "p2", string>;

여기서 K는 string을 갖는 속성과 T는 K속성들이 따르는 타입을 의미한다. 결과는 아래 그림처럼 나온다.

타입T1이 적용된 A1타입이다. 타입T1 적용된 A2타입이다.

enum type과 활용

mapped 타입 이용하여 enum타입 활용도를 높일 수 있다고한다. 아래 예시를 보자.

enum DogKind {
  Maltese,
  Retriever,
  Shiba,
}

const dog_age1 = {
  [DogKind.Maltese]: 2,
  [DogKind.Retriever]: 1,
  [DogKind.Shiba]: 3,
};

dog_age1과 같이 DogKind enum타입에 숫자를 기록할 수 있다. 만약 DogKind에 enum은 추가가 되고, dog_age1에 값을 할당 안하는 실수를 범할 수 있을 것이다. mapped 타입을 사용하면 이런 실수를 방지할 수 있다고 한다.

enum DogKind {
  Maltese,
  Retriever,
  Shiba,
}

const dog_age2: { [key in DogKind]: number } = {
  [DogKind.Maltese]: 2,
  [DogKind.Retriever]: 1,
  [DogKind.Shiba]: 3,
};

위 예시처럼 사용하면, enum이 추가될 때마다 해당 값을 입력하지 않으면 에러가 발생할 것이다.

참조

[Mapped Types, TypeScript Docs, 2022년08월10일 접속]
https://www.typescriptlang.org/docs/handbook/2/mapped-types.html

profile
개발자준비중

0개의 댓글