타입 스크립트 - 제네릭

김영준·2023년 7월 29일
0

TIL

목록 보기
39/91
post-thumbnail

함수에서 제네릭 사용하기

현재는 string 타입의 매개 변수밖에 받지 못한다.


다른 타입도 받게 하려면 함수 오버로딩을 사용하면 된다.


하지만 추가해야되는 타입이 늘어날 때마다 타입 선언부와 구현부가 복잡해진다.
이럴 때 제네릭 문법으로 훨씬 심플하게 작성할 수 있다.
함수명 뒤에 <> 내부에 타입 변수를 선언한다.
T는 타입 변수이다. 함수 호출 부분에서 타입이 전달되고 함수 내부에서 재사용 할 수 있다.


함수 호출 부분에서 타입을 생략해도 가능하다.
그 이유는 타입 추론 때문인데 타입 스크립트가 첫번째 인수를 받아보고 a: T 구문에서 a는 string 타입이니까 T가 string 타입이라고 추론하기 때문이다.


하지만 한 가지 문제가 발생한다. string, number, boolean을 제외한 다른 타입도 사용이 가능하다는 것이다.

toObj(null, null) // 가능

이 때 타입 변수 뒤에 extends 키워드를 사용하여 제약 조건이라는 것을 추가할 수 있다.


인터페이스에서 제네릭 사용하기

인터페이스에도 제네릭 사용이 가능하다.
toObj의 반환 타입을 정확히 모를 때 interface 이름 뒤에 타입 변수를 선언한다.
내부에서 재사용이 가능하기 때문에 반환되는 값의 타입으로 T를 지정할 수 있고 함수가 호출된 후 타입 추론으로 인해 T의 타입이 추론되기 때문에 반환값의 타입도 자동으로 결정된다.


타입 변수를 연달아서 사용 가능하다. (순서대로 타입이 지정됨)


type 별칭에서 제네릭 사용하기

배열 타입도 허용 가능하게 만들기 위해 interface가 아닌 type 별칭을 사용하여 union 타입으로 선언해준다. (정확히는 튜플 타입)


중복되는 타입 제네릭 선언을 타입으로 만들어서 사용할 수 있다.


클래스에서 제네릭 사용하기

마찬가지로 클래스 이름 뒤에 제네릭을 작성한다.


만약 위 예제에서 string 타입만 허용하게 하고 싶으면 제약 조건을 추가하면 된다. 따라서 클래스 제네릭 부분에 <T extends string>을 추가하였다.


하지만 Orange를 전달하는 과정에서 에러가 발생하였다.

그 이유는 제약 조건을 추가하게 되면 타입 스크립트는 T라는 타입 변수를 최대한 구체적인 타입으로 이해하려고 한다.

따라서 T는 string 타입이긴 한데 타입 추론을 통해서 초기화 될 때 들어왔던 "APPle", "Banana", "Cherry" 만 타입 변수로 정의가 된 것이다.

쉽게 보면 type T = "Apple" | "Banana" | "Cherry"의 타입을 가진 것이다.

해결 방법은 타입 스크립트가 잘못된 추론을 하지 않도록 명시적으로 타입을 작성하는 것이다. 인스턴스를 생성할 때 클래스 뒤에 타입을 지정하면 된다.

profile
꾸준히 성장하는 개발자 블로그

0개의 댓글