728x90
타입스크립트 맵드 타입 정리

❓상황

타입스크립트 기본 개념 중 하나인 mapped type 정리

 

📖 맵드 타입이란?

기존에 정의되어 있던 타입을, 새로운 타입으로 변환해주는 문법이다.

아래는 변환 예시이다.

// 기존 타입
type userType = {
  name: string,
  email: string
}

// 새로운 타입
type newUserType = {
  name: number,
  email: number
}

 

🧮 정리

개요

위의 변환 예시를 보면, 기존 타입의 key는 동일하나, value는 달라진것을 알 수 있다.

이것을 변환하는 방법을 이해하기 위해서는 typeof, keyof, in 키워드를 알고 있어야한다.

 

typeof

자바스크립트에 typeof 키워드가 존재하는데, 자바스크립트의 typeof 다음에 적힌 변수(= 자료형)이 무슨 타입인지 알려주는 역할을 한다.

console.log(typeof 1) // number
console.log(typeof 'str') // string
console.log(typeof true) // boolean
console.log(typeof {}) // object

 

⭐type alias의 key를 이용한 문자열 리터럴 타입 변환: keyof

기존 타입의 key를 모아서, key로 이루어진 문자열 리터럴 타입으로 만들어준다.

type Type = {
  a: number,
  b: string,
  c: boolean
}

// type TypeKeys = 'a' | 'b' | 'c';
type TypeKeys = keyof Type;

 

여기서 중요한 점은 keyof는 기존 타입의 key를 모을 수 있지만, object의 key를 모을 수는 없다.

이를 해결하기 위해서는 keyof와 typeof 두개를 사용해야한다.

 

⭐object의 key를 이용한 문자열 리터럴 타입 변환: keyof + typeof

객체의 key를 모아서, key로 이루어진 문자열 리터럴 타입을 만들 수 있다.

const obj = {
  a: 1,
  b: 'str',
  c: true
}

// type ObjKeys = "a" | "b" | "c"
type ObjKeys = keyof typeof obj;

 

⭐⭐type alias의 value를 이용한 문자열 리터럴 타입 변환: keyof + typeof

지금까지 key로 이루어진 새로운 타입으로 변환하는 작업을 했다.

이번에는 value로 이루어진 새로운 타입으로 변환하는 작업이다.

 

우선, 기존 타입의 key를 문자열 리터럴 타입으로 변환하고, 기존 타입에 인덱스접근을 통해 기존 타입의 value에 접근하여 value로 이루어진 문자열 리터럴 타입을 만들 수 있다.

type Type = {
  a: number,
  b: string,
  c: boolean
}

// type TypeValues = string | number | boolean
type TypeValues = Type[keyof Type]

 

⭐⭐object의 value를 이용한 문자열 리터럴 타입 변환: keyof + typeof

이번에는 object의 value로 이루어진 문자열 리터럴 타입을 만드는 방법이다.

const obj = {
  a: 1,
  b: 'str',
  c: true
}

// type ObjValues = string | number | boolean
type ObjValues = typeof obj[keyof typeof obj]

 

만약, 문자열 객체 타입으로 만들고 싶다면 obj에 as const를 붙이면 된다.

 

⭐⭐⭐기존의 객체 타입(type alias)를 새로운 객체 타입 변환: keyof + typeof + in

자바스크립트에서 in 키워드가 있는데, in 키워드를 통해 특정 값이 object(array도 된다)의 property인지 boolean 값으로 반환된다.

const obj = {
  a: 1,
  b: 'str',
  c: true
}

console.log('a' in obj) // true

 

 여기서 in 키워드는 object가 가진 여러개의 property에 접근한다는 점을 이해하자.

 

타입스크립트에서의 in도 유사하게 사용가능하다.

in 키워드는 문자열 리터럴 타입이 가진 유니온 타입들에 접근할 수 있다.

이를 이용하여, 기존 객체타입을 새로운 객체타입으로 만들 수 있다.

type createObjType<T> = {
  [Property in keyof T]: T[Property]
}

type ObjType = {
  value: string,
  onChange: Function,
  disabled: boolean
}

/* type NewObjType = {
  value: string;
  onChange: Function;
  disabled: boolean;
} */
type NewObjType = createObjType<ObjType>

 

맨 처음에 예시로 든 타입 변환은 아래와 같이 하면 된다.

// 기존 타입
type createNewType<T> = {
  [Property in keyof T]: number
}

type userType = {
  name: string,
  email: string
}

type newUserType = createNewType<userType>


/* type newUserType = {
     name: number,
     email: number
} */

 

⭐⭐⭐⭐object를 새로운 객체 타입으로 변환: keyof + typeof + in

해당 내용을 주제로 삼은 이유가 있다.

 

개발 프로젝트를 진행하면서 값을 props로 넘겨주게 되면 타입을 지정해줘야 하는 경우가 많다.

객체를 보고 수동으로 타입을 지정해준다고 치면, 나중에 props로 넘겨주는 객체에 property를 추가하거나 제거할 경우에 타입까지 수정해야하는 경우가 발생한다.

처음부터 객체를 타입으로 변환해주는 mapped type 문법을 이용하면, 번거로움을 해결 할 수 있다.

const obj = {
  a: 1,
  b: 'str',
  c: true
}

type createObjType<T> = {
  [Property in keyof T]: T[Property]
}

/* type ObjType = {
     a: number,
     b: string,
     c: boolean
*/ }
type ObjType = createObjType<typeof obj>

 

참고

https://javascript.plainenglish.io/using-typescript-mapped-types-like-a-pro-be10aef5511a

복사했습니다!