오늘은 TypeScript의 제네릭에 대해서 알아보겠습니다!

참고한 강좌 영상은 아래 첨부합니다 :)

목차


    0. 함수에서의 제네릭

    제네릭(Generic)을 이용하면 클래스나 함수, 인터페이스를 다양한 타입으로 재사용할 수 있습니다.
    선언할 때는 타입 매개변수만 적어주고, 생성하는 시점에 사용하는 타입을 결정하는 것입니다.

    배열을 매개변수로 받아서 배열의 사이즈를 구하는 getSize 함수를 만들어보았습니다.


    지금은 숫자가 들어간 배열 형태만 넣을 수 있습니다.
    만약 문자가 들어간 배열을 넣으면 당연히 오류가 발생합니다.


    같은 함수인데 문자를 꼭 넣고 싶다구요?!
    이렇게 매개 변수의 타입이 바뀌었는데 동일한 함수를 재사용하고 싶다면 함수 오버로딩을 사용하거나 아니면 간단하게 유니온 타입을 이용해서 선언할 수 있습니다.


    그런데 이번에는 객체를 받고싶을 수 있습니다.
    이렇게 하나하나 예외가 생길 때마다 추가해줘야 할까요..?!

    너무 길어진다....


    이럴 때 쓸 수 있는 것이 바로 제네릭입니다.
    제네릭은 함수의 이름 뒤에 꺾쇠괄호를 넣고 그 안에 타입을 적어줍니다.
    이것을 타입 파라미터라고 부르는데, 일반적으로 T를 사용하는데 다른 문자나 단어를 넣어도 똑같이 동작합니다.
    이렇게 만들면 특정 타입을 전달받아서 함수 내에서 사용할 수 있게 됩니다.

    아래 예시를 가져왔습니다. <T>를 붙여주고, 배열의 속성을 T[]로 바꿔주면 정상적으로 돌아가게 됩니다.
    코드가 훨씬 깔끔해졌죠?!


    이제 실제로 함수를 사용할 때 타입을 정의해줍니다.
    (사실 굳이 정의하지 않아도 타입스크립트는 const 상수의 타입을 읽고 알아서 타입을 인식하지만, 보다 엄밀하게 만들기 위해서는 정확한 타입을 꺾쇠괄호 안에 명시하는 것이 좋습니다.)


    1. 인터페이스의 제네릭

    이번에는 인터페이스 안에서 사용해보도록 하겠습니다.

    아래 예시에서는 option의 형태가 정해지지 않았습니다.
    어떤게 들어올 지 모르기 때문에 제네릭 타입 T를 넣어줘서, 객체도 받고 문자열도 받을 수 있게 만들어 주었습니다.


    object를 받는 경우 object의 값으로 받아야 하는 요소들의 타입이 결정되어 있다면 아래와 같이 바로 선언해줄 수도 있습니다!


    2. 종합선물세트

    이번에는 두 가지 케이스를 섞어보겠습니다.
    User, Car, Book 인터페이스를 선언하고, showName 함수를 만들었습니다.


    들어오는 데이터의 타입을 정해주기 위해서 제네릭 타입을 선언했습니다.
    그런데 오류가 발생했네요?


    이것은 T로 들어오는 매개변수 데이터가 반드시 name이라는 요소가 있다고 장담할 수 없기 때문에 생기는 오류입니다.
    실제로 Book에는 name이 없죠..!

    이 문제를 해결하기 위해서는 꺽쇠괄호에서 T를 선언한 이후에 아래처럼 extends { name: string } 을 붙여주면 됩니다.
    이렇게 만들면 어떤 T 타입이 매개변수로 올 것인데, 그 타입은 name이 string인 객체를 확장한 형태라고 알려주는 것입니다.
    이러면 다양한 모습의 객체가 올 수 있겠지만, 항상 name은 string을 가지고 있게 됩니다.
    만약 name이 없거나 string이 아니라면 book을 전달할 때 name이 없다는 오류가 발생하게 됩니다.


    정말 만약에 name이 없다면 아래처럼 book에 밑줄이 그어지게 됩니다.


    Car 클래스 내부의 요소중에 name을 boolean 형태로 바꿔보았습니다.
    그러면 name의 속성이 boolean이 되고, showName에서 car를 불러올 때 name이 string 속성이 아니므로 빨간 밑줄이 생기게 됩니다!!


    반응형
    • 네이버 블로그 공유하기
    • 네이버 밴드에 공유하기
    • 페이스북 공유하기
    • 카카오스토리 공유하기