개발/typescript

타입스크립트 기초 문법 - 제네릭 기초

모그 2024. 1. 2. 15:18

제네릭


function func(value:any){
	return value;
}

let num = func(10); //any 타입
let str = func("string") //any 타입

 

any타입인 변수에 다른 타입의 값을 넣어도 any타입이 된다.

반환값 value를 기준으로 타입 추론이 되기때문이다.


    ex.
    let Test:any
    Test=10;
    Test //any 타입
 

 

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) //오류