제네릭의 사전적 정의
- 제네릭은 C#, Java 등의 언어에서 재사용성이 높은 컴포넌트를 만들 때 자주활용되는 특징입니다. 특히, 한가지 타입보다 여러가지타입에서 동작하는 컴포넌트를 생성하는데 사용됩니다.
제네릭을 사용하는 이유
아래의 코드는 인자를 하나 넘겨 받아 반환해주는 함수입니다.
함수의 인자와 반환값은 모두 string으로 되어있지만 만약 여러가지 타입을 허용하고 싶으면 any를 사용할 수 있습니다.
function logText(text: string): string {
return text;
}
이렇게 any로 한다고해서 함수의 문제가 있는것은 아니지만
함수의 인자로 어떤 타입이 들어갔고 어떤 값이 반환되는지는 알 수 없습니다. (any라는 타입은 검사하지 않기때문)
function logText(text: any): any {
return text;
}
이러한 문제를 해결하는 것이 제너릭입니다.
함수의 이름뒤에 <T>라는 코드를 추가했습니다. 그리고 함수의 인자와 반환값에 모두 T라는 타입을 추가합니다.
이렇게 되면 함수의 입력값에 대한 타입과 출력값에 대한 타입이 동일한지 검증할 수 있습니다.
function logText<T>(text: T): T {
return text;
}
함수에서의 제네릭
제네릭(Generic)을 이용하면 클래스나, 함수, 인터페이스를 다양한 타입으로 재사용할 수 있습니다.
선언할 때는 타입 매개변수만 적어주고, 생성하는 시점에 타입을 결정하는 것입니다.
배열을 매개변수로 받아서 배열의 사이즈를 구하는 getSize함수를 만들어보겠습니다.
지금은 숫자가들어간배열, 문자가있는 배열 형태만 넣을 수 있습니다.
여기서 객체를 받고 싶거나 또는 boolean배열 값을 받고 싶으면 ' | ' 유니온타입을 이용해 계속 적어줘야할까요?
이럴때 쓸 수 있는 것이 제네릭 입니다.
제네릭은 함수의 이름 바로 뒤에 꺽쇠괄호를 넣고 그 안에 타입을 적어줍니다.
이것을 타입 파라미터라고 부르는데, 일반적으로 T를 사용하는데 다른 문자나 단어를 넣어도 똑같이 작동합니다.
각 배열타입마다 유니온 코드를 작성해주지 않아서 코드가 훨씬 깔끔해졌습니다.
arr1과 arr2에서 함수를 호출할때 타입을 정의해주었는데 굳이 정의해주지 않아도 타입스크립트는 const상수의 타입을 읽고 알아서 타입을 인식하지만, 보다 엄밀하게 만들기 위해서는 정확한 타입을 명시하는 것이 좋습니다.
인터페이스의 제네릭
아래 인터페이스 Mobile에는 option의 형태가 정해지지 않았습니다.
어떤게 들어올지 모르기 때문에 제네릭 타입 T를 넣어줘서, 객체도 받고 문자열도 받을 수 있게 만들어 주었습니다.
object를 받는 경우 object의 값으로 받아야 하는 요소들의 타입이 결정되어 있다면
아래와 같이 바로 선언해줄 수도 있습니다.
이렇게 하나의 인터페이스를 선언하고
다른 모습의 객체들을 생성할 수 있습니다.
다른케이스를 보겠습니다.
User, Car, Book 인터페이스를 선언하고, ShowName함수를 만들었습니다.
함수의 매개변수의 타입을 정해줘야합니다. 제네릭을 사용해서 타입을 정해주겠습니다.
제너릭을 설정해줬는데 에러가 발생했습니다.
이것은 T로 들어오는 매개변수 데이터가 반드시 name이라는 요소가 있다고 장담할 수 없기 때문에 발생합니다.
실제로 Book에 name이 없습니다.
아래처럼 Book에 name을 추가해주어도 여전히 발생합니다.
따라서 extends {name:string} 을 붙여줍니다.
이렇게하면 어떤 T타입이 매개변수로 오는데 이 타입은 name이 string인 객체를 확장한 형태 라고 알려주는 것입니다.
다양한 모습의 객체가 올 수 있겠지만 ,항상 name은 string을 가지고 있게 됩니다.
만약 name이 없거나 string이 아니라면 book을 전달할 때 name이 없다는 오류가 발생하게 됩니다.
추가로 Car클래스의 name을 boolean 타입으로 변경해보면
그러면 name의 속성이 boolean이 되고, showName에서 car를 불러올때 name이 string속성이 아니므로
에러가 뜹니다.
'프론트엔드 > typescript' 카테고리의 다른 글
타입스크립트 - 유틸리티 타입 (0) | 2023.10.25 |
---|---|
타입스크립트 - 클래스 (0) | 2023.10.23 |
타입스크립트 - 리터럴타입,유니온/교차타입 (0) | 2023.10.23 |
타입스크립트 - 함수 (0) | 2023.10.23 |
타입스크립트 - 인터페이스(Interface) (1) | 2023.10.22 |