타입 조작이란??
- 타입을 조작한다는 것은 기본 타입이나 별칭 또는 인터페이스로 만든 원래 존재하던 타입들을 상황에 따라 유동적으로 다른 타입으로 변환하는 기능이다.
- 제네릭도 함수나 인터페이스, 타입 별칭, 클래스 등에 적용해서 상황에 따라 달라지는 가변적인 타입을 정의할 수 있기 때문에 타입을 조작하는 기능에 포함된다.
- 타입스크립트에서는 제네릭 이외에도 다양한 타입 조작 기능을 제공한다.

- 첫번째로 살펴볼 타입 조작 기능은 객체, 배열, 튜플 타입으로부터 특정 프로퍼티나 특정 요소의 타입만 추출하는
인덱스드 엑세스 타입이다.

- 두번째로는 객체 타입으로부터 해당 타입 내에 정의된 프로퍼티의 키들을 유니온 타입으로 추출하는
키오브 타입에 대해서 살펴보자.

- 세번째로는 마치 자바스크립트의 맵 함수처럼 기존의 객체 타입을 기반으로 새로운 객체 타입을 만드는
맵드 타입에 대해서 알아본다.

- 네번째로는 기존의 스트링 리터럴 타입을 기반으로 정해진 패턴의 문자열만 포함하는
템플릿 리터럴 타입에 대해 살펴본다.

인덱스트 엑세스 타입
- 인덱스드 엑세스 타입은 인덱스를 이용해 다른 타입내의 특정 프로퍼티의 타입을 추출하는 타입이다.
인덱스드 엑세스 타입은 객체, 배열, 튜플에 사용할 수 있다.
- 다음과 같은 게시글을 표현하는 객체 타입이 있고, 게시글도 하나의 변수로 만들었다. 그리고 게시글에서 작성자의 이름과 아이디를 붙여서 출력하는 어떤 함수가 있다.

- 그런데 매개변수의 타입을 이렇게 정의하면 나중에 Post 타입의 author 프로퍼티의 타입이 수정되면 매개변수의 타입도 그때 마다 계속 수정해줘야 하는 불편함이 존재한다.
- 이럴 때에는 다음과 같이
인덱스드 엑세스 타입을 이용해 Post에서 author 프로퍼티의 타입을 추출해 사용하면 편리하다.

Post["author"]는 Post 타입으로부터 author 프로퍼티의 타입을 추출한다. 그 결과 author 매개변수의 타입은 {id : number, name: string, age:number}가 된다.
- 이때 대괄호 속에 들어가는 String Literal 타입인 “author” 를 인덱스 라고 부른다. 그래서 인덱스를 이용해 특정 타입에 접근한다고 하여
인덱스드 엑세스 타입이라 부른다.
- 주의할 점은 인덱스에는 값이 아니라 타입만 들어갈 수 있다.
- 따라서 다음과 같이 “author”를 문자열 값으로 다른 변수에 저장하고 다음과 같이 인덱스로 사용하려고 하면 오류가 발생한다.

- 또 한가지 주의할 점은 인덱스에 존재하지 않는 프로퍼티 이름을 쓰면 오류가 발생한다. (당연하죠?)

- 또는 다음과 같이 인덱스를 중첩하여 사용할 수도 있다.

배열 요소의 타입 추출하기
- 인덱스드 엑세스 타입은 객체 프로퍼티의 타입 뿐만 아니라 특정 배열의 요소 타입을 추출하는데에도 이용할 수 있다.

- 인덱스드 엑세스 타입을 이용해 다음과 같이 이 PostList 배열 타입에서 하나의 요소의 타입만 뽑아올 수 있다.
- PostList[number]는 PostList 배열 타입으로부터 요소의 타입을 추출하는 인덱스드 엑세스 타입이다. 이렇듯 배열의 요소 타입을 추출할 때에는 인덱스에
number 타입을 넣어주면 된다.
- 또 인덱스에 다음과 같이
Number Literal 타입을 넣어도 된다. 숫자와 관계없이 모두 Number 타입을 넣은 것과 동일하게 동작한다.

튜플의 요소 타입 추출하기
- 튜플의 각 요소들의 타입 또한 다음과 같이 인덱스드 엑세스 타입으로 쉽게 추출할 수 있다.

- 한가지 주의할 점은 튜플 타입에 인덱스드 엑세스 타입을 사용할 때 인덱스에 number 타입을 넣으면 마치 튜플을 배열처럼 인식해서 배열 요소의 타입을 추출하게 된다.
keyof & typeof 연산자
keyof 연산자
- keyof 연산자는 객체 타입으로부터 프로퍼티의 모든 key들을 String Literal Union 타입으로 추출하는 연산자이다.

- Person 객체 타입을 정의하고 해당 타입을 갖는 변수를 하나 선언한다.
- 그리고 getPropertyKey 함수를 만든다. 이 함수는 두개의 매개변수가 있으며, 두번째 매개변수 key에 해당하는 프로퍼티의 값을 첫번째 매개변수 person에서 꺼내 반환한다.
- 이때 key의 타입을 “name” | “age”로 정의했는데, 이렇게 정의하면 다음과 같이 Person 타입에 새로운 프로퍼티가 추가되거나 수정될 때 마다 이 타입도 계속 바꿔줘야 한다.
- 굉장히 비효율적이다. 그래서 이럴때는 Keyof 연산자를 이용하면 좋다.

- keyof 연산자는 위와 같이 keyof 타입 형태로 사용하며 타입의 모든 프로퍼티 key를 String Literal Union 타입으로 추출한다.
- 따라서 keyof Person의 결과값은
“name” | “age” | “location”이 된다.
- 그래서 아무리 프로퍼티가 추가되거나 변경되어도 keyof 연산자를 사용하면 유니언 타입으로 추출 가능하다!!
- 한가지 주의할 점은 keyof 연산자는 오직 타입에만 적용할 수 있는 연산자 라는 점이다. 따라서 다음과 같이 값과 함께 사용하려고 하면 오류가 발생한다.

Typeof와 Keyof 함께 사용하기
- typeof 연산자는 자바스크립트에서 특정 값의 타입을 문자열로 반환하는 연산자이다.
- 그러나 다음과 같이 타입을 정의할 때 사용하면 특정 변수의 타입을 추론하는 기능도 가지고 있다.
- 그래서 어떤 변수의 타입을 뽑아내는 역할을 할 수 있다.

- typeof person의 결과로 person 객체형태로 불려오고, keyof를 통해서 타입들을 유니언 형태로 뽑아낼 수 있다.
맵드 타입
맵드 타입은 기존의 객체 타입을 기반으로 새로운 객체 타입을 만드는 타입 조작 기능이다.
- 유저 정보를 관리하는 간단한 프로그램의 일부분을 만든다고 가정한다.

- 그런데 updateUser 함수의 매개변수 타입이 User 타입으로 되어 있어서 수정하고 싶은 프로퍼티만 골라서 보낼 수 없는 상황이다.
- 어쩔 수 없이 다음과 같이 새로운 타입을 만들어 주어야 한다.

- 그런데 User 타입과 PartialUser 타입이 지금 서로 중복된 프로퍼티를 정의하고 있다. 중복 코드는 좋지 않아.
- 따라서 이럴 때 바로 맵드 타입을 이용하면 좋다.

- PartialUser 타입을 맵드 타입을 이용해 아까와 동일한 타입으로 정의했다.
[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
- 여기에 대괄호 뒤에 선택적 프로퍼티를 의미하는
물음표(?) 키워드가 붙어있으므로 모든 프로퍼티가 선택적 프로퍼티가 되어 결론적으로 이 타입은 다음과 같은 타입이 된다.

- 이렇듯 맵드 타입을 이용하면 간단한 한줄의 코드 만으로 중복 없이 기존 타입을 변환할 수 있다.
- 여기서 keyof 연산자를 이용해 한번 더 업그레이드 하면 다음과 같다.

- 주의사항으로는 맵드 타입은 인터페이스에서는 사용할 수 없다. 무조건 타입 별칭으로만 사용해야한다.
- 실무에서도 굉장히 많이 사용되는 방식이니 꼭 기억하도록!
템플릿 리터럴 타입
템플릿 리터럴 타입은 타입 조작 기능들 중 가장 단순한 기능으로 템플릿 리터럴을 이용해 특정 패턴을 갖는 String 타입을 만드는 기능이다.

- Color와 Animal은 각각 3개의 String Literal 타입으로 이루어진 Union 타입이다. 그리고 ColoredAnimal은 Color와 Animal을 조합해 만들 수 있는 모든 가지수의 String Literal 타입으로 이루어진 Union 타입이다.
- Color나 Animal 타입에 String Literal 타입이 추가되어 경우의 수가 많아질 수록 ColoredAnimal 타입에 추가해야하는 타입이 점점 많아지게 된다.
- 이럴 때 바로 템플릿 리터럴 타입을 이용하면 좋다.

- 문자열로 여러가지 상황들을 표현해야할때 유용하게 사용할 수 있다. 빈도는 그닥...;;
이미지 출처: <한 입 크기로 잘라먹는 타입스크립트>
https://www.inflearn.com/course/%ED%95%9C%EC%9E%85-%ED%81%AC%EA%B8%B0-%ED%83%80%EC%9E%85%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8?inst=68d752f7&utm_source=instructor&utm_medium=referral&utm_campaign=inflearn_%ED%8A%B8%EB%9E%98%ED%94%BD_promotion-link