타입스크립트 (10) 타입 조작하기

김태완·2024년 11월 21일
post-thumbnail

타입 조작이란??

  • 타입을 조작한다는 것은 기본 타입이나 별칭 또는 인터페이스로 만든 원래 존재하던 타입들을 상황에 따라 유동적으로 다른 타입으로 변환하는 기능이다.
  • 제네릭도 함수나 인터페이스, 타입 별칭, 클래스 등에 적용해서 상황에 따라 달라지는 가변적인 타입을 정의할 수 있기 때문에 타입을 조작하는 기능에 포함된다.
  • 타입스크립트에서는 제네릭 이외에도 다양한 타입 조작 기능을 제공한다.
  1. 첫번째로 살펴볼 타입 조작 기능은 객체, 배열, 튜플 타입으로부터 특정 프로퍼티나 특정 요소의 타입만 추출하는 인덱스드 엑세스 타입이다.
  2. 두번째로는 객체 타입으로부터 해당 타입 내에 정의된 프로퍼티의 키들을 유니온 타입으로 추출하는 키오브 타입에 대해서 살펴보자.
  3. 세번째로는 마치 자바스크립트의 맵 함수처럼 기존의 객체 타입을 기반으로 새로운 객체 타입을 만드는 맵드 타입에 대해서 알아본다.
  4. 네번째로는 기존의 스트링 리터럴 타입을 기반으로 정해진 패턴의 문자열만 포함하는 템플릿 리터럴 타입에 대해 살펴본다.

인덱스트 엑세스 타입

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

profile
중고

0개의 댓글