타입스크립트 제네릭

KHS·2022년 8월 28일
0

typescript

목록 보기
3/4
post-thumbnail

제네릭이란?

자바스크립트에서는 없던 개념인데 자바 같은 컴파일 언어에서는 비교적 일반적인 문법이다.

제네릭은 데이터 타입을 일반화(generalize)한다 라고 보면 되는데 어떤 클래스, 파라미터, 리턴 타입에 대해 타입을 지정해주는 것이다.

제네릭을 사용하면 어떤 데이터 타입이 오가는지 보다 명확히 할 수 있어 코딩 중 발생하는 문제를 줄일 수 있고 다양한 데이터 타입에 대해 대응할 수 있어서 코드 양을 줄일 수 있는 효과도 있다.

문법

function logAndReturn<T>(param: T): T {
  console.log(param);
  return param;
}

const str = logAndReturn('10'); //str의 데이터 타입은 string
const num = logAndReturn(10); //num의 데이터 타입은 number

Union Type과 비교

메소드 파라미터를 Union Type으로 설정하면 제네릭과 마찬가지로 여러가지 데이터 타입에 대해 대응할 수 있지만
return 결과도 Union Type으로 설정되기 때문에 이후 사용하기에 불편한 상황이 발생한다.

function logAndReturn(param: string | number) {
  console.log(param);
  return param;
}

const str = logAndReturn('10'); //str의 데이터 타입은 string | number
str.split(' '); //split은 string 타입에만 사용할 수 있으므로 error 발생

제네릭 타입 제한

function logAndReturn<T>(param: T[]): T {
  console.log(param.length);
  param.forEach((child) => {
    console.log(child);
  }
  return param;
}

const str = logandReturn('abc'); //배열 타입이 아니므로 error 발생
const arr = logAndReturn(['abc', 'def']);
//인터페이스 상속으로 타입 제한
interface LengthType {
  length: number;
}

function logAndReturn<T extends LengthType>(param: T): T {
  console.log(param);
  return param;
}

const num = logAndReturn(10); //number 항목에는 length 값이 없으므로 error 발생
const str = logAndReturn('10');
const arr = logAndReturn(['abc', 123]);
const obj = logAndReturn({leng: 10}); //object 항목에 length 값이 없으므로 error 발생
//인터페이스의 키에 대한 상속으로 타입 제한
interface Product {
  name: string;
  price: number;
  stock: number;
}

function getItemInfo<T extends keyof Product>(param: T): T {
  console.log(param);
  return param;
}

const name = getItemInfo('name');
const amount = getItemInfo('amount'); //Product 항목에 amount 속성이 없으므로 error 발생

유틸리티 타입

타입스크립트 작성 중 정의되어 있는 타입, 인터페이스에 대해 유동적으로 타입을 정의할 수 있는 방법이다.

다양한 타입이 정의돼있으며 공식 문서를 확인하자.

링크 - 타입스크립트 유틸리티 타입

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

//Pick은 타입에서 정의된 특정 항목을 가져오는데 쓰인다.
type child1 = Pick<Parent, 'name'|'age'>;

//Omit은 Pick과 반대로 동작한다.
type child2 = Omit<Parent, 'address'>;

//Partial은 내부 항목을 Optional 값으로 정의할 수 있다.
type child3 = Partial<Parent>;
===
interface child3 {
  name?: string;
  age?: number;
  address?: string;
}
//mappedType은 기존 타입에서 정의된 항목의 속성을 재정의한다.
type Names = 'kim' | 'lee' | 'park';
type Ages = { [K in Names]: number}; //string 타입을 number 타입으로 변환

const ages: Ages = {
  kim: '20', //number 타입이 아니므로 error 발생
  lee: 30,
  park: 40
}
profile
Java & Vue ...

0개의 댓글