TS - 인덱스 타입 사용시 정확한 key Type 추론방법

이수빈·2024년 11월 8일
0

Typescript

목록 보기
12/17
post-thumbnail

TS PlayGround

인덱스 타입

  • 객체 내에 속성을 동적으로 정의하거나, 엑세스 할때 사용하는 타입이라고 생각하면 된다.

  • 4가지 정도의 유형이 있다.

IndexSignature

  • 타입이 정적으로 정의되지 않을 때 사용

  • 동적으로 프로퍼티 할당 가능

interface StringMap {
  [key: string]: string; // key is a string, value is also a string
}

const myMap: StringMap = {
  name: "Alice",
  city: "Wonderland",
};

인덱스 유형 쿼리 (keyof)

  • 연산자 keyof는 객체 유형의 모든 키의 유니온 유형을 반환한다.
interface Person {
  name: string;
  age: number;
}

type PersonKeys = keyof Person; // "name" | "age"

인덱스 액세스 유형(T[K])

  • 객체에서 특정 속성을 ACCESS할때 사용한다.
interface Person {
  name: string;
  age: number;
}

type NameType = Person["name"]; // string
type AgeType = Person["age"]; // number

매핑된 유형

  • 인덱스 타입을 사용해 기존 타입을가지고 새로운 타입을 만들 수도 있다.
type ReadOnly<T> = {
  readonly [P in keyof T]: T[P];
};

interface Person {
  name: string;
  age: number;
}

type ReadOnlyPerson = ReadOnly<Person>;
// equivalent to: 
// {
//   readonly name: string;
//   readonly age: number;
// }

인덱스 타입에서 type 정확하게 추론하기

  • 예시상황을 보자

  • 아래와 같은 타입에서 => 각각의 프로퍼티의 타입을 정확하게 뽑아내고 싶을때는 어떻게 해야할까?

type Test = {  a?: string;  b?: number;  c?: Array<{ aa?: number; bb?: string }>;}
  • 처음에 시도한 방법은 => key값을 keyof연산자를 통해 key타입을 넣어주면 알아서 추론 할 수 있을 것 같았다.

  • 하지만, key타입 자체가 리터럴타입이라 => 추론되는 결과 타입도 각 key에 맞는 value type이 아니라, 객체 전체의 유니온타입으로 추론되는 것을 알 수 있었다.

const getTest1 = (params: Test, key: keyof Test) => {  return params[key];}

const value: Test = {} as const;

const result = getTest1(value, 'c');// string | number | { aa?: number; bb?: string; }[] | undefined
  • 하지만, 제너릭과 제약조건을 함께 이용하면 이 문제를 해결 할 수 있다 .

  • 여기서 제너릭으로 Key를 받고, 이를 keyof 연산자로 key리터럴타입으로 제약조건을 걸어준다.

  • TS는 그럼 들어오는 파라미터는, key값 type중 무조건 하나라고 인식하고, 해당 key에 맞는 value를 추론 할 수 있게 되는 것이다.


const getTest2 = <Key extends keyof Test>(params: Test, key: Key) => { return params[key];}

const value: Test = {} as const;

const result2 = getTest2(value, 'c');//  { aa?: number; bb?: string;}[] | undefined
  • 아래와 같이 result2는 의도에 맞는 arrayType으로 추론된다.
profile
응애 나 애기 개발자

0개의 댓글