본문 바로가기
Language/Typescript

타입스크립트 : Object To Union

by hsloth 2024. 3. 17.

 

코드를 작성하다가 문득, Object를 Union으로 바꾸는 방법에 대해 고민이 생겼다.

그래서 Object를 Union으로 바꾸어 보기로 마음 먹고 코드를 작성해보았다.

 

내가 작성한 타입들은 다음과 같다.

1. 객체의 속성들의 리턴 타입을 유니온으로 변환하여 리턴하는 타입

2. 객체의 속성 값을 변환하여 유니온 타입으로 리턴

3. 객체의 각 속성을 하나씩 분리하여 유니온 타입으로 리턴

 

일단 기본적인 타입은 아래와 같다

type Human = {
  name: string;
  age: number;
  height: number;
  weight: number;
};

 

 

객체의 속성들의 리턴 타입을 유니온으로 변환

간단하다. 다음 두 가지 방법으로 변환할 수 있다. 방법 2가 더 쉽다.

// 방법1
type HumanToUnionOnlyReturnType = {
  [P in keyof Human]: Human[P];
}[keyof Human];

// 방법2
type HumanToUnionOnlyReturnType2 = Human[keyof Human];

// 리턴 타입
HumanToUnionOnlyReturnType = string | number

 

key of 구문을 사용하면 key가 유니온 형식으로 하나씩 입력되기 때문에 자동으로 유니온 타입으로 변환되어 리턴되게 된다.

 

 

객체의 속성 값을 변환하여 유니온 타입으로 리턴

이 경우도 간단하다. 객체를 { key: string, value: string } 타입으로 변환해서 리턴해보자.

type HumanToUnionChangedForm = {
  [P in keyof Human]: {
    key: P;
    value: Human[P];
  };
}[keyof Human];

 

리턴 타입

 

 

객체의 각 속성을 하나씩 분리하여 유니온 타입으로 리턴

사실, 원래 이걸 목표로 실험을 여러가지 실험을 하고 있었다.

 

처음 도전했던 코드다... P를 속성 값으로 사용할 수 없어서 실패했다.

type HumanToUnionFail = {
  [P in keyof Human]: P extends keyof Human ? {
    `${P}`: Human[P];
  }: '';
};


type HumanToUnionFail2 = {
  [P in keyof Human]: P extends keyof Human ? {
    [`${P}`]: Human[P];
  }: '';
};

 

 

그래서 객체 뒤에 [keyof Object] 를 붙이면 유니온 타입으로 도출된다는 점에 착안하여 다음과 같이 타입을 만들 수 있었다.

type HumanToUnion = {
  [P in keyof Human]: {
    [P2 in P]: Human[P2];
  };
}[keyof Human];

 

리턴 타입

완벽하다! 하지만, 주의할 점이 있다.

나는 현재 타입스크립트 5.3.2 버전을 사용하는데, 해당 타입을 지정해준 변수를 사용할 때 에러를 발생시키지 못하는 경우가 있다.

아마... 타입스크립트의 구조적 타이핑 때문에 발생하는 문제같다.

 

 

타입이 객체의 유니온 타입인데도 에러를 뱉지 않고 있다. 이 문법은 주의해서 사용하도록 하자.