공부기록/웹 개발

[타입스크립트] keyof , in keyof

_우지 2022. 10. 6. 22:05

partial 과 pick 에 대해서 내가 직접 타이핑을 하다 생긴 궁금증이다.

 

partial 을 타이핑을 할때는 다음처럼 in keyof 를 사용했다.

다음처럼 말이다.

interface Profile {
  name: string;
  age: number;
  married: boolean;
}

type P<T> = {
  [Key in keyof T]?: T[Key];
};

const newZeroCho: P<Profile> = {
  name: "zero",
  age: 29,
;

 

그런데 Pick 을 타이핑 할때에는 in 만 사용한다. 머리가 어지러웠다.

interface Profile {
  name: string;
  age: number;
  married: boolean;
}

type P<T, S extends keyof T> = {
  [Key in S]: T[Key];
};

const newZeroCho: P<Profile, "name" | "age"> = {
  name: "zerocho",
  age: 29,
};

 

우선 이해를 하려면 keyof 가 어떤 역할을 해주는지 알아야한다.

다음과 같은 인터페이스가 있을때에 keyof Profile 을 해주면 어떻게 될까?

코드 아래에 결과를 주석으로 달아놓았다.

interface Profile {
  name: string;
  age: number;
  married: boolean;
}

// result   keyof Profile ====> 'name' | 'age' | 'married'

 

이제 다시 Patial 코드를 보자. 주석에 코멘트을 달았다.

interface Profile {
  name: string;
  age: number;
  married: boolean;
}

type P<T> = {
  [Key in keyof T]?: T[Key];
  // 순서
  // Key in 'name' | 'age' | 'married'
  // 하나씩 iterate 가 된다. 'name' -> 'age' -> 'married' 순으로
};

const newZeroCho: P<Profile> = {
  name: "zero",
  age: 29,
;

 

또한 Pick 을 보자.

interface Profile {
  name: string;
  age: number;
  married: boolean;
}

type P<T, S extends keyof T> = {
  [Key in S]: T[Key];
  // 왜 이번에는 Key in keyof S 가 아닐까?
  // 그 이유는 이미 S extends keyof T 로 선언이 되어 있기 때문이다.
  // S 의 범위는 extends 로 인해 'name' | 'age' | 'married' 가 되었다.
  // 또한 제네릭 S 는 'name' | 'age' 이기때문에 in 만 써주어도 iterate 가 가능한 것이다.
};

const newZeroCho: P<Profile, "name" | "age"> = {
  name: "zerocho",
  age: 29,
};

 

적장 물리쳤다..