[TypeScript] 섹션8. 타입 조작하기

jaehoon ahn·2025년 2월 18일

TypeScript

목록 보기
12/14
post-thumbnail

인덱스드 타입

인덱스를 이용해서 다른 타입내에 특정 프로퍼티의 타입을 추출하는 타입

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

function printAuthorInfo1(author: { id: number; name: string }) {
  console.log(`${author.name}-${author.id}`);
}
function printAuthorInfo2(author: { id: number; name: string }) {
  console.log(`${author.name}-${author.id}`);
}
function printAuthorInfo3(author: { id: number; name: string }) {
  console.log(`${author.name}-${author.id}`);
}
const post: Post = {
  title: "게시글 제목",
  content: "게시글 본문",
  author: {
    id: 1,
    name: "제노",
    age: 27,
  },
};
  • 각각 타입을 추가해도 되지만, author 매개변수를 받는 함수가 여러개가 되고 프로퍼티가 추가가 되면 각각 수정을 해줘야 한다.
  • 이때 특정 프로퍼티의 타입을 뽑아올 수 있는 인덱스드 엑세스 타입을 쓰면 된다.

문법

function printAuthorInfo(author: Post["author"]) {
  console.log(`${author.name}-${author.id}`);
}
  • Post["author"] 이렇게 작성해주면 된다. 타입명["프로퍼티타입"];
  • 여기서 string 리터럴 타입인 "author"와 같은 것을 인덱스라고 부른다.
  • 인덱스를 이용해서 특정 타입의 프로퍼티에 접근한다고 해서 인덱스드 액세스 타입이라고 부르는 것

타입의 하나의 프로퍼티만 가져오는 방법

⇒ ex) id 프로퍼티의 타입만 가져오는 방법

type PostList = {
  title: string;
  content: string;
  author: {
    id: number;
    name: string;
    age: number;
  };
}[];
// 타입명[타입]["프로퍼티"]
function printAuthorInfo2(author: Post["author"]["id"]) {
  console.log(`${author.name}-${author.id}`);
}

배열 타입으로부터 요소의 타입을 추출하기

⇒ 타입명[타입]

const post2: PostList[number] = {
  title: "게시글 제목",
  content: "게시글 본문",
  author: {
    id: 1,
    name: "제노",
    age: 27,
  },
};

튜플에서 특정 타입 뽑아내기

type Tup = [number, string, boolean];
type Tup0 = Tup[0];
type Tup1 = Tup[1];
type Tup2 = Tup[2];

keyof 연산자

interface Person {
  name: string;
  age: number;
}
function getPropertyKey(person: Person, key: "name" | "age") {
  return person[key];
}
  • 이렇게 유니온 연산자를 사용하면, 타입이 많이지면 그떄마다 추가를 해줘야하는 불편함이 있다.
  • 이럴 때 keyof 연산자를 사용해주면 된다.
keyof 타입명
.
.
function getPropertyKey(person: Person, key: keyof Person) {
  return person[key];
}
  • keyof Person은 Person 객체 타입으로부터 모든 프로퍼티 키를 유니온 타입으로 추출
  • 그래서, 타입은 "name" | "age"로 추출이 된다.
  • 프로퍼티가 추가되면 "name" | "age" | "추가된 프로퍼티" 이런식으로 추가가 된다.
  • 프로퍼티가 바뀌거나 추가가 되더라도 keyof로 아주 쉽게 객체타입의 프로퍼티 타입을 유니온 타입으로 추출할 수 있다.

typeof와 같이 사용

keyof typeof 변수
.
.
type Person2 = typeof person;

function getPropertyKey2(person: Person, key: keyof typeof person) {
  return person[key];
}
  • person 변수의 타입을 추론해서 Person2 타입 별칭에 정의를 해준다.

맵드 타입

⇒ interface에서는 만들 수 없다. type 별칭 사용!

type PartialUser = {
  [key in "id" | "name" | "age"]: User[key];
  
};
.
.
function updateUser(user: User) {
  // ... 수정하는 기능
}
updateUser({
  age: 25,
});
  • age만 바꾸고 싶을 때, id, name은 변경되지 않는데 일일히 써줘야 하는 불편함이 있다. 즉, 변경되는 값만 보내고 싶은 것
  • key가 무엇이 될 수 있는지: 어떤 타입을 가질 것인지.
  • [key in "id" | "name" | "age"]: key값으로는 id, name, age가 있을 수 있다는 의미

선택적 프로퍼티로 만들기

[key in "id" | "name" | "age"]?: User[key];

맵드 타입으로 불리언 타입으로 만들기

type BooleanUser = {
  [key in "id" | "name" | "age"]: boolean;
  // [key in keyof User]: boolean
};
  • 프로퍼티의 개수가 많아져서 유니온 타입으로 만들기 힘들 때
  • keyof 연산자 사용

모든 프로퍼티에 readonly 추가하기

type ReadonlyUser = {
  readonly [key in keyof User]: User[key];
};

템플릿 리터럴 타입

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

type ColoredAnimal = "red-dog" | "red-cat" | "red-chicken" | "black-dog";
  • 일일히 유니온 타입으로 써주면 시간이 오래걸리고, 수정이 된다면 다 고쳐줘야 한다.
  • 이럴 때 쓰는게 템플릿 리터럴 타입

사용법

type ColoredAnimal2 = `${Color}-${Animal}`;

0개의 댓글