TIL

TypeScript 강의 (7) ( 유틸리티 타입 )

황민도 2024. 7. 29. 15:24

내일배움캠프 스파르타 코딩클럽

 

Partial<T> 타입이란?

- `Partial<T>`  타입은 타입 T의 모든 속성을 선택적으로 만들어요!
- 이를 통해 기존 타입의 일부 속성만 제공하는 객체를 쉽게 생성할 수 있습니다.
- 아직, 무슨 말인지 잘 모르시겠죠? 예제를 살펴볼게요!

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

const updatePerson = (person: Person, fields: Partial<Person>): Person => {
  return { ...person, ...fields };
};

const person: Person = { name: "Spartan", age: 30 };
const changedPerson = updatePerson(person, { age: 31 });

- 우선, Person이라는 인터페이스는 name, age라는 속성으로 구성이 되어있어요!
- updatePerson 함수를 자세히 봐보세요. 2번째 인자로 `Partial<Person>` 타입의 fields를 받고 있어요.
- 이 field라는 인자가 구성이 될 수 있는 경우의 수는 다음과 같아요.
    - name이라는 속성만 있어도 됩니다.
    - age라는 속성만 있어도 됩니다.
    - name, age라는 속성이 둘 다 있어도 됩니다.
    - 이 밖의 상황은 허용하지 않아요!
        - 예를 들어, `{ name, gender }`와 같이 기존에 없는 속성을 넣어서는 안됩니다!
- 이렇게 Partial<T> 타입으로 유연하게 타입의 속성을 선택해서 객체를 만들 수 있어요!

 

Required<T> 타입이란?

- Partial<T> 타입과는 반대로 `Required<T>` 타입은 타입 T의 모든 속성을 필수적으로 만듭니다!
- 다시 말해서, T 타입 객체에 정의된 모든 속성이 반드시 전부 제공이 되는 객체를 생성해야 할 때 쓰이죠!

interface Person {
  name: string;
  age: number;
  address?: string; // 속성 명 뒤에 붙는 ?가 뭘까요
}

- 아까 봤던 Person이라는 인터페이스에 address라는 속성이 새로 생겼어요.
- 그런데, address에 `?` 라는 문자가 붙었네요.
    - 이 친구는 선택적 속성입니다.
    - 있어도 되고 없어도 되는 친구라는 것이에요!
- 하지만,  address를 필수적으로 받아야 하는 제약사항이 있다고 하면 다음과 같이 할 수 있어요!

type RequiredPerson = Required<Person>;

- 이렇게 Required<T> 타입을 통해 선언하면 address 입력도 필수가 되는 것입니다!

 

 Readonly<T> 타입이란?

- 이름부터 역할이 유추되는 `Readonly<T>` 타입은 타입 T의 모든 속성을 읽기 전용(read-only)으로 만들어요!
- 이를 통해 readonly 타입의 속성들로 구성된 객체가 아니어도 완전한 불변 객체로 취급할 수 있어요!

interface DatabaseConfig {
  host: string;
  readonly port: number; // 인터페이스에서도 readonly 타입 사용 가능해요!
}

const mutableConfig: DatabaseConfig = {
  host: "localhost",
  port: 3306,
};

const immutableConfig: Readonly<DatabaseConfig> = {
  host: "localhost",
  port: 3306,
};

mutableConfig.host = "somewhere";
immutableConfig.host = "somewhere"; // 오류!

- DatabaseConfig는 불변 객체라고 할 수 없어요. 왜냐하면 host가 readonly가 아니죠!
- 하지만, ReadOnly<T> 타입으로 불변 객체로 만들 수 있으니 걱정마세요!

 

 

 Pick<T, K> 타입이란?

- `Pick<T, K>` 유틸리티 타입은 타입 T에서 K 속성들만 선택하여 새로운 타입을 만듭니다!
- 이를 통해 타입의 일부 속성만을 포함하는 객체를 쉽게 생성할 수 있어요.

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

type SubsetPerson = Pick<Person, "name" | "age">;

const person: SubsetPerson = { name: "Spartan", age: 30 };

 - SubsetPerson은 Person이라는 인터페이스에서 name, age 속성만 선택해서 구성된 새로운 타입이에요!

 

 Omit<T, K> 타입이란?

- `Omit<T, K>` 유틸리티 타입은 타입 T에서 K 속성들만 제외한 새로운 타입을 만듭니다!
- Pick<T, K> 유틸리티 타입과는 반대의 동작이죠!
- 이를 통해 기존 타입에서 특정 속성을 제거한 새로운 타입을 쉽게 생성할 수 있어요.

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

type SubsetPerson = Omit<Person, "address" | "age">;

const person: SubsetPerson = { name: "Alice", age: 30 };

 - 여기서 SubsetPerson 타입은 Person 타입에서 address, age 속성을 제외한 새로운 타입입니다!

 - Pick 유틸리티 타입 과 다른 장점은 만약 Person 타입 속성이 30개 정도 정의 되어있다면 빼는 것이 더욱 빠르고 효율적     이기 때문이다.

 

 

- 여기서 소개한 유틸리티 타입 외에도 다양한 유틸리티 타입이 있습니다. 아래 링크를 참고하세요!
    - https://www.typescriptlang.org/ko/docs/handbook/utility-types.html
- 이러한 유틸리티 타입을 잘 다루면 필요에 따라 복잡한 타입을 쉽게 조작할 수 있어요!