[TS] 타입 조작하기

DT-HYUNJUN·2023년 12월 17일

Typescript

목록 보기
10/11

타입 조작하기

인덱스트 엑세스 타입

인덱스드 엑세스 타입은 타입의 인덱스를 이용해 특정 속성의 타입을 추출하는 타입이다.

interface Post {
  title: string
  content: string
  author: {
    id: number
    name: string
  }
}

Post 인터페이스의 author속성의 타입인 { id: number; name: string; }을 추출하기 위해선 인덱스드 엑세스 타입을 사용하면 된다.

인덱스드 엑세스 타입을 사용하기 위해서는 []안에 타입을 적어주면 된다.

const author: Post["author"] = {
  id: 0,
  name: "Park",
}

여기서 주의할 점은 []안에 값이 아니라 타입만 들어갈 수 있다.

const authorType = "author"

const author: Post[authorType] = {	// error
  id: 0,
  name: "Park",
}

배열 타입으로부터 추출하기 위해서는 Post[number]["author"] 이런식으로 추출하면 된다.

keyof 연산자

keyof연산자는 객체 타입으로부터 속성 key들을 문자열 리터럴 유니온 타입으로 추출하는 연산자다.

interface Person {
  name: string
  age: number
}

function getPropertyKey(person: Person, key: "name" | "age") {
  return person[key]
}

"name" | "age" 의 타입을 keyof 연산자를 이용해서 구현하면 아래와 같이 구현할 수 있다.

interface Person {
  name: string
  age: number
}

function getPropertyKey(person: Person, key: keyof Person) {
  return person[key]
}

Mapped 타입

Mapped 타입은 기존의 객체 타입을 기반으로 새로운 객체 타입을 만드는 타입 조작 기능이다.

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

User타입을 모두 선택적 속성을 가진 타입인 새로운 속성을 만들기 위해서는 각 속성에 ?키워드를 붙여주면 된다.

interface OptionalUser {
  id?: number
  name?: string
  age?: number
}

그러나 이렇게 일일이 ?를 붙여주는 작업은 비효율적이다.

속성이 무수하게 많거나 User타입에 새로운 속성이 생기면 변경사항을 일일이 적용해줘야 한다.

이럴 때 사용하는 타입이 Mapped 타입이다.

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

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

만약 readonly 키워드를 추가하고 싶으면 앞에 붙여주면 된다.

type ReadonlyOptionalUser = {
  readonly [key in keyof User]?: User[key]
}

템플릿 리터럴 타입

템플릿 리터럴 타입특정 패턴을 갖는 string타입을 만드는 간단한 기능이다.

type Color = "red" | "black" | "green"
type Animal = "dog" | "cat" | "chicken"

type ColoredAnimal = "red-dog" | "red-cat" | "red-chicken" | "black=dog" | ...

이런식으로 Color타입과 Animal타입을 엮는 ColoredAnimal타입을 만든다고 할 때 사용할 수 있는 타입이 템플릿 리터럴 타입이다.

type Color = "red" | "black" | "green"
type Animal = "dog" | "cat" | "chicken"

type ColoredAnimal = `${Color}-${Animal}`

0개의 댓글