제네릭(Generics)
제네릭이란?
타입이 마치 함수의 매개변수 값으로 설정되는 개념으로, 주로 재사용성이 좋은 컴포넌트를 만들 때 자주 사용된다.
//logText 옆에 <T>은 제네릭을 쓸 것이라고 명시하는 붑분
//text 옆에 T는 함수호출 시 받은 매개변수의 타입으로 설정하는 부분
//{} 앞에 T는 리턴값도 타입을 매개변수의 타입으로 설정하는 부분
function logText<T>(text: T):T{
console.log(text);
return text
}
logText<string>("하이")
//호출 시 <string>을 사용하면 함수의 매개변수와 리턴 값의 타입이 string으로 설정되는 것이고,
//없다면 타입이 "하이"가 된다.
//이 때 하이를 타입추론을 통해 적당한 타입으로 설정된다.
제네릭을 사용하면 함수가 어떤 타입을 받을지 미리 정하지 않고, 넘겨주는 인자를 통해서 함수가 받는 타입과 리턴타입을 설정하게 된다.
이전 문법과 제네릭의 차이점
- 기존 문법
function logText(text:string):string{
console.log(text)
return text;
}
function logNumber(text:number):number{
console.log(text)
return text;
}
기존의 문법의 경우 인수의 매개변수의 타입이 다를 때마다 해당하는 함수를 선언해주어야 하기 때문에 불필요한 코드를 반복하게 된다.
- 유니온 문법
function logText(text : string|number): string|number{
console.log(text);
//text. << 이때가 문제
return text;
}
유니온 문법을 사용할 경우 인풋에 대한 문제는 해결되지만, 함수안에서 text에 대한 api를 사용하고자 할 때와 함수의 리턴값을 받은 변수가 어떤 api를 사용하고자 할 때 string과 number에서 공통적으로 사용되는 api만을 사용할 수 있다.
- 제네릭 문법
function logText<T>(text : T): T{
console.log(text);
return text;
}
const str = logText<string>('a') // 이 때 함수의 매개변수와 리턴 타입은 string
const num = logText(10) //이 때 함수의 매개변수와 리턴 타입은 number
하나의 함수를 정의하여 여러가지의 타입에 대해서 적용가능하며, 여러가지 타입에 대한 적절한 api를 사용할 수 있다.
인터페이스에 제네릭 선언방법
interface Dropdown<T> {
value: T;
selected: boolean;
}
const obj: Dropdown<string> = { value : "abc", selected: true};
// value값이 string이 아니면 에러
인터페이스에 타입을 T로 준 부분에 타입은 호출 시에 <타입>에서 준 타입으로 설정된다.
제네릭 타입제한
제네릭을 엄격하게 사용하고 싶을 경우 사용
- 타입제한
function logTextLength<T>(text : T) : T{
text.length // error
return text;
}
logTextLength('hi');
logTextLength 함수 입장에서는 매개변수로 어떤 값이 들어올지 모르기 때문에 length를 사용할 경우 에러를 표시하게 된다.
function logTextLength<T[]>(text : T[]) : T[]{
text.length // length api를 가지고 있는 []을 타입으로 선언했기 때문에 성공
return text;
}
logTextLength<string[]>(['hi']);
따라서 위와 같이 []형태로 만들어주면 기본적으로 logTextLength함수는 매개변수로 배열을 받기 때문에 length를 사용할 수있다. 물론 인수값으로는 배열값으로 넣어줘야하는 문제가 있다. 우리는 인수로 string값을 넣고 length를 사용하고 싶기 때문에extends를 사용한다.
- extends
interface LengthType{
length: number;
}
function logTextLength<T extends LengthType>(text : T):number{
const len = text.length;
return len;
}
logTextLength<string>('a') // 1
logTextLength<string[]>('a') // 1
extends는 특정 속성을 가진 타입만 허용하는 키워드이다. 즉, 원래 T라는 타입에는 length가 없지만 extends를 사용하여 인수 중에 length라는 메소드를 사용할 수 있는 타입은 허용한다.
- keyof
interface User{
name: string;
email: string;
password: string;
age: number
}
function logName<T extends keyof User>(value :T):void{
console.log(value)
}
logName('name');
특정 객체의 키 값을 인수로 허용할 때 keyof 키워드를 사용한다. 키값을 키워드로 사용하는 것 뿐이고 반환 값은 의미를 두지 않아도 된다.
Author And Source
이 문제에 관하여(제네릭(Generics)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@leejh96/제네릭Generics저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)