[Type Script] Utility Types, 유틸리티 타입

Hwanhoon KIM·2023년 7월 27일
0

typescript

목록 보기
1/2

Utility Types란

유틸리티 타입은 TypeScript에서 제공하는 내장 타입들로, 자주 사용되는 일반적인 타입 변환 및 조작 작업을 쉽게 수행할 수 있도록 도와주는 기능이다.

자주 쓰이는 타입

Required<T>

만들어진 타입<>로 감싸고, 앞에 Required를 붙이면, interface로 정의된 객체의 타입을 임의로 복사 변경할 수 있다. (물론 본체는 건드리지 않는다.)

밑의 예시에서 Required<Person>으로 fields의 타입을 Required, Person으로 바꿔준다.

fields는 결국 Person타입으로 name: stringage: number 여야됨을 설정함과 동시에 Required로 이것은 꼭 채워야하는 사항임까지 설정하는 것이다.

[error] Required이므로 fields에 Person 타입의 요소가 하나라도 오지 않거나 다른 요소가 추가되면 에러를 낸다.

interface Person {
  name: string
  age: number
}

type newPerson = Required<Person>

const updatePerson = (person: Person, fields: newPerson): Person => {
  return { ...person, ...fields }
}

const khh: Person = { name: 'khh', age: 29 }

console.log(updatePerson(khh, { name: 'd', age: 35 }))


updatePerson(khh, { name: 'd'})
// [error]
// Argument of type '{ name: string; }' is not assignable to parameter of type 'Required<Person>'.
// Property 'age' is missing in type '{ name: string; }' but required in type 'Required<Person>'.ts(2345)
// 아주 친절하게 property 'age' is missing이라고 알려주는 것을 알 수 있다.

type newPerson = Required<Person>에서 다음과 같이 바꿔줄 수 있다. 아래 방법이 더 간단하기에 앞으로 이 방법을 쓸 것 같다.

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

Partial<T>

Required의 예와 같은 예시에서 fields의 타입을 Partial으로 지정하면,

<Person> 타입에 name, age에서 name만 써도 되거나 age만 써도 되는 등 문자 그대로 partial하게 사용 가능하다.

[error] 의 양식에 벗어나는 것을 입력하면 에러가 발생한다.

interface Person {
  name: string
  age: number
}

type newPerson = Paritial<Person>

const updatePerson = (person: Person, fields: newPerson): Person => {
  return { ...person, ...fields }
}

const khh: Person = { name: 'khh', age: 29 }

console.log(updatePerson(khh, { age: 35, number: 123 }))
// [error]
// Argument of type '{ age: number; number: number; }' is not assignable to parameter of type 'Partial<Person>'.
// Object literal may only specify known properties, and 'number' does not exist in type 'Partial<Person>'.

Readonly<T>

타입 앞에 Readonly를 붙여 그 타입은 변경이 불가능하게 만드는 유용한 유틸리티 타입이다.

[error] Readonly를 지정된 값을 변경하는게 불가능해진다.

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

const zambia: Readonly<Person> = {
  name: 'zambia',
  age: 45,
};

zambia.age = 10;
console.log(zambia);

// [error]
// Cannot assign to 'age' because it is a read-only property.ts(2540) 

Record<T>

Record는 쉽게 말해서 객체의 key: value 쌍을 미리 등록해 두는 것이다.

type recordObjType = Record<string, number>

const examResult: recordObjType = {
	Science: 100,
	English: 100,
	Computer: 100
}

Pick<T>

Pick은 미리 정의된 타입에 일 부분만 골라서(pick) 사용한다.

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

type PersonName = Pick<Person, 'name' | 'age'>;

const khh: PersonName = {
  name: 'khh',
  age: 14,
};

Omit<T>

Omit, 문자 그대로 생략하는 것이다.

Omit<T, 타입의 키 이름(of 키:벨류 쌍)> ⇒ T라는 타입을 가져오는데 오른쪽에 적혀있는 키 이름을 제외하고 가져온다.

[error] omit한것을 가져오려고 하면 에러가 난다.

interface Person {
  name: string;
  age: 29;
  city: string;
}

type PersonWithOnlyAge = Omit<Person, 'name' | 'city'>;

const khh: PersonWithOnlyAge = { age: 29, city: 'khh' };

[error]
  // Type '{ age: 29; city: string; }' is not assignable to type 'PersonWithOnlyAge'.
//  Object literal may only specify known properties, and 'city' does not exist in type 'PersonWithOnlyAge'.

자주 쓰이지는 않는 것들(작성자 기준)이지만 중요해보이는 것들

ReturnType<T>

특정 함수에서 반환되는 값의 정확한 타입을 모를 때 사용하는 것 같다.

const add = (x: number, y: number): number => {
return x + y;
};

type returnOfAddFunction = ReturnType<typeof add>;

const subtract = (x: number, y: number): returnOfAddFunction => {
return x - y;
};

Parameters<T>

GPT >>>

Parameters<Type>은 TypeScript에서 제공하는 유틸리티 타입 중 하나로, 함수 타입 Type의 매개변수 타입들을 추출하는데 사용됩니다.

예를 들어, 다음과 같은 함수가 있다고 가정해봅시다.

function greet(name: string, age: number): void {
console.log(`Hello, ${name}! You are ${age} years old.`);
}

이제 Parameters를 사용하여 greet 함수의 매개변수 타입들을 추출해보겠습니다.

type GreetParams = Parameters<typeof greet>;

위의 코드에서 GreetParamsgreet 함수의 매개변수 타입들을 담은 튜플 타입 [(string | number)]가 됩니다.

Parameters는 함수의 타입을 추출하기 때문에, 해당 함수를 타입으로 전달할 때에는 함수 자체를 전달해야 합니다. 즉, typeof 연산자를 사용하여 함수의 타입을 전달해야합니다.

이를 통해 함수의 매개변수 타입들을 추출하여 다른 곳에서 재사용하거나 함수 타입을 동적으로 조작하는데 유용하게 사용할 수 있습니다. 예를 들어, 제네릭 함수를 만들 때 함수의 매개변수 타입들을 활용하여 타입 검사를 수행하거나 매개변수의 개수나 타입에 따라 다른 동작을 수행하는 등의 상황에서 활용할 수 있습니다.


Conditional Types (조건부 타입)

GPT >>>

조건부 타입(Conditional Types)은 TypeScript에서 도입된 고급 타입으로, 조건에 따라 타입을 결정할 수 있도록 하는 기능입니다. 조건부 타입은 T extends U ? X : Y와 같은 형식으로 작성되며, TU를 확장(extends)하는지에 따라 X 또는 Y 중 하나의 타입이 결정됩니다.

조건부 타입을 사용하여 다양한 상황에서 타입을 조작할 수 있습니다. 주로 제네릭 타입과 함께 사용되어 유연한 타입 정의를 가능하게 합니다.

예시를 통해 조건부 타입을 살펴보겠습니다.

type IsNumber<T> = T extends number ? true : false;

type Result1 = IsNumber<number>;      // true
type Result2 = IsNumber<string>;      // false
type Result3 = IsNumber<boolean>;     // false

위의 예시에서 IsNumber라는 조건부 타입을 정의했습니다. 이 타입은 입력된 제네릭 타입 Tnumber 타입을 확장하는지를 검사하여 true 또는 false를 반환합니다. number 타입을 확장하는 경우 true를 반환하고, 그렇지 않은 경우 false를 반환합니다.

이 외에도 다양한 상황에서 조건부 타입을 사용할 수 있습니다. 예를 들어, 유니온 타입의 각 멤버를 조건적으로 처리하거나, 제네릭 타입에 따라 다른 타입을 리턴하는 등의 활용이 가능합니다.

조건부 타입은 TypeScript 코드의 유연성을 높이고, 타입 안정성을 유지하는 데에 유용하게 사용됩니다. 하지만 조건부 타입을 복잡하게 사용하면 코드의 가독성이 떨어질 수 있으므로 적절하게 사용해야 합니다.

profile
Fullstack Developer, I post about HTML, CSS(SASS, LESS), JavaScript, React, Next, TypeScript.

0개의 댓글