본문 바로가기

Javascript

Typescript generic & util

Typescript 쓰면서 알게된 것들을 정리해보고자 한다.
피드백 & 수정사항 환영합니다아

Typescript 의 제네릭

제네릭 : 클래스나 함수에서 사용할 타입을 함수나 클래스를 사용할 때 결정하는 프로그래밍 기법

함수에서 흔한 사용 예

function first<T>(arr: T[]): T {
  return arr[0];
}

// number 로 타입을 명시해 주었다.
first<number>([1,2,3]);
// type 명시하지 않아도 string 으로 추론한다.
first(['a','b','c']);

generic extends

특정 유형에 속한 type 을 정의하고 싶다면 extends 를 활용하자!
아래 예제에서는 Type 에 length 속성이 존재하지 않기 때문에 error 발생한다.

function foo<Type>(arg: Type): Type {
  console.log(arg.length); // Property 'length' does not exist on type 'Type'.
  return arg;
}

모든 type에서 작동하게 하는 것보다, 위와 같이 length property 를 가진 type 에 작동하게 하고 싶다면

type OptionValue = string | {length: number};
function foo<Type extends OptionValue>(arg: Type): Type {
  console.log(arg.length); // 이제 Type 이 length property 를 가질 수 있다는 것을 알기 때문에 error 발생 안한다.
  return arg;
}

foo({length :3});
foo("abddc")

Typescript Util

Typscript는 특정 Type 에서 원하는 모양으로 바꾸고 싶을때 유용한 util 들을 제공한다.

Partial, Omit, Pick

  • Partial : T 의 any sub keys
  • Omit<T, 'x'> : T 의 모든 key 중 x 만 제외
  • Pick<T, 'x' |'y' |'z'> : T 에서 x, y, z key 만 선택

하나씩 살펴보자.
다음과 같은 Props 를 정의했다고 해보자.

interface Props {
    id : number,
    title: string,
    lines : string[]
}

먼저 Omit 은 다음과 같이 사용할 수 있다.

type excludeProps = Omit<Props, 'id'>  //  Props 에서 id 만 제외한 타입이 된다.

Partial 과 Pick 의 사용예는 다음과 같다.

// Props에서 id, title 만 가져온 type 이 만들어진다.
function foo({id, title}:Pick<Props, 'id'|'title'>){ ...}

// return 값은 Props 안에 어떤 property 라도 가지고 있으면 괜찮다.
// Partial 을 적어주지 않으면 retrun type 에 error 가 발생한다.
function foo2(state: Props) : Partial<Props> {
    return { id : 123}; // OK!
}

& 연산

& 연산은 Type 들을 합쳐주는 기능을 한다. 예시를 보자

interface Props {
  data: number;
  label: string;
}

interface Input<T> {
  page: T;
}

function Test<Type>({page}: Input<Type & Props>) {
  page.data = 1;
  page.label = "changed";
  console.log(page); // {"data":1, "label" : "changed", "title" : "Title" }
}

Test<{title:string}>({page: {data: 0, label:'none', title:'Title'}});

위와 같이 이상한 코드를 짤일은 없겠지만 Test 함수에서 page 의 타입을 Prsops 와 Type 을 합친 타입으로 받게 했다.
저렇게 하면 함수 내에서 page 를 Props type 처럼 쓸 수 있다.