타입스크립트 기초 문법 - 제네릭 기초
제네릭
function func(value:any){
return value;
}
let num = func(10); //any 타입
let str = func("string") //any 타입
any타입인 변수에 다른 타입의 값을 넣어도 any타입이 된다.
반환값 value를 기준으로 타입 추론이 되기때문이다.
Test 변수를 any타입으로 설정한 후 다른 타입을 재할당해도 any타입인것을 생각해보면 된다.
이렇게 만들어진 함수에
num.toUpperCase();를 실행해도 오류를 감지하지 못한다.
그래서 필요한 것이 모든 타입의 값을 적용할 수 있는 제네릭 함수이다.
제네릭 기본 문법
function func(value){
return value;
}
여기서 아래처럼 매개변수의 타입만 설정해주면 타입스크립트 문법이다.
function func(value:string){
return value;
} // func 의 타입은 string으로 자동 추론
꺽쇠를 열고, 타입변수 T를 선언한다.
매개변수와 반환값의 타입에도 타입변수 T를 선언한다.
☘️ 타입변수 = 타입 파라미터 = 제네릭 타입변수 = 제네릭 타입 파라미터
function func<T>(value:T):T{
return value;
}
이렇게 선언된 타입변수 T는 범용적이고 일반적인 타입으로 추론되기때문에
원하는 타입이 있다면 구체적으로 설정해야한다.
function func<T>(value:T):T{
return value;
}
let ten = func(10) // number 타입
let ten2 = func<10>(10) // number literal 타입
let arr = func([10,100]) //배열타입
let arr2=func<[number,number]>(10,100) //튜플타입
제네릭 적용 사례
✔️ 타입변수의 타입이 2개 이상 필요할 때
제네릭함수를 하나의 타입으로만 사용 할 경우 예시, 아래와 같이 오류메시지 발생!
function func<T>(a:T,b:T) {
return [b,a]
}
let arr = func(["string",100])
//타입이 통일되지 않아 오류메시지 발생
아래와 같이 타입변수를 두 개로 분리한다.
function func<T,U>(a:T,b:U) {
return [b,a]
}
✔️다양한 배열 타입이 인수가 될 때
function ArrayFirst<T>(data:T){
return data[0]
}
let num = ArrayFirst([10,11,12]) //number 타입
let str = ArrayFirst(["string",100,"text",121]) // number | string 타입이 된다.
number | string 타입으로 추론되었기때문에 return문에서는 data[0] 자리에 숫자가 올지 문자가 올지 알 수 없다.
좀 더 확실히 하고싶다면 튜플타입을 활용한다.
✔️다양한 배열 타입이 인수가 되는 경우, 타입을 좀 더 정확히 정하고 싶을 때
function ArrayFirst<T>(data:[T, ...unknown[]]){
return data[0];
}
let str = ArrayFirst(["string",100,"text",121]) // string 타입
✔️타입 변수 제한하기 ( 확장 {extends} 활용 )
function getLength<T>(data:T){
return data.length; // 반환값은 any타입으로 추론되어 오류 발생
}
function getLength<T extends {length:number}>(data:T){
return data.length;
}
// length 프로퍼티를 갖고있는 객체타입을 확장한 것이 T, 즉 T는 length:number 를 갖고있는 객체의 서브타입이 된다.
let num = getLength([1,2,3]) //3
let str = getLength("test") //4
let obj = getLength( {length:100} ) // 100
let unde = getLength(nudefined) //오류