[TIL]Typescript generic

ohoho·2024년 10월 14일

슬기로운스터디

목록 보기
28/54

오늘 공부한것 & 기억할 내용

call signiture

  • 함수 위에 마우스 커서 올렸을때 파라미터와 리턴값의 타입 정보
//함수에 대한 타입 정의
type Add = (a:number, b:number) => number

const add:Add = (a,b) = a + b

Overloading

  • 함수가 여러개의 call signiture를 가지고 있을때 문제가 발생한다.
//인자가 여러개 있을경우
//다른 개수의 파라미터를 가지게 되면 나머지 파라미터도 타입을 지정해줘야함
type Number = {
	(a:number, b:number) : number
  	(a:number, b:number, c:number) : number
}
//c를 옵션으로 넣어준다.
const Add:Number = (a,b,c?:number) => {
	if(c) return a+b+c
  	a+b
}

//두개의 속성을 가진 객체
type Config = {
    path : string,
    state : object
}
//함수 타입 정의 
type Push =  {
    (path: string):void //void는 값을 반환하지 않는다
    (config: Config):void
} 

const push:Push = (config) => {
    if(typeof config === "string"){ //문자열인지 확인
        console.log(config) //문자열 출력
        }else {
        console.log(config.path) //Config 객체 안의 path 출력
        }
}

Polymorphism

  • Polymorphism이란 다형성으로 여러타입을 받아들임으로서 여러 형태를 가진다
  • 제네릭은 선언 시점이 아니라 생성 시점에 타입을 명시하여 하나의 타입만이 아닌 다양한 타입을 사용할 수 있도록 하는 기법이다.
  1. 타입의 인자마다 새로 작성해 줘야하는 문제점
type SuperPrint = {
	(arr: number[]): void
    (arr: boolean[]): void
    (arr: string[]): void
    (arr: (number|boolean)[]): void
}
 
const superPrint: SuperPrint = (arr) => {
	arr.forEach(i => console.log(i))
}
 
superPrint([1, 2, 3, 4])
superPrint([true, false, true, false])
superPrint(["a", "b", "c"])
superPrint([1, 2, true, false])
  1. generic를 이용해서 전달하는 인자를 추론해서 함수를 실행시킨다.
type SuperPrint = {
  //이름은 원하는 것 아무거나 가능하다<T>가 될 수 도 있음
  <TypePlaceholder>(arr: TypePlaceholder[]): TypePlaceholder;
}
 
const superPrint: SuperPrint = (arr) => arr[0]
 
const a = superPrint([1, 2, 3, 4]);
const b = superPrint([true, false, true]);
const c = superPrint(["a", "b", "c"]);
conts d = superPrint([1, 2, true, false]);

📌generic을 사용하는 이유

  • call signature를 작성할 때, 타입이 어떤것인지 미리 알 수 없을때 사용한다.
  • generic은 call signature를 생성한다. (타입이 어떤것인지 보임)
  • any를 사용하지 않고 generic사용하는 이유는 generic은 타입을 추론해주고 any는 타입 추론을 하지 못한다. (any는 에러문구 뜨지 않음)

generic 다양한 예시

//함수에 바로 사용한 경우
function number<T>(a : T[]) {
  return a[0]
}
console.log(number(['1a', '2a', 3, 4]))
// output> 1a

//화살표 함수에서 사용한 경우
const arr = <T>(a: T[]) => a[0]
console.log(arr(['ㄱ', 'ㄴ', 'ㄷ', 'ㄹ'])) 
// type> string, output> ㄱ 
console.log(arr([1, 2, 3, 4]
// type> number, output> 1 
                
                
type PlayName<E> = {
  name: string,
  extraInfo: E, // 제네릭
};

type ExtraInfo = {age: number}

type MeInfo = PlayName<ExtraInfo> 

const johan : MeInfo  = {
  name: "johan",
  extraInfo: {
    age: 23
  },
};               

Polymorphism generic 참고

배운점 & 느낀점

Polymorphism 타입이 여러가지일때 generic type으로 <T> 지정해주면 call signiture를 여러번 안써줘도 되서 편리하다는점을 배웠다.

여기서 드는 궁금증은 그럼 모든걸 generic을 쓰면 편리하지 않을까 생각했는데 추후 유지보수때 타입이 뭔지 혼란스러울 수 있고, 과도하게 사용하면 가독성이 떨어지고 코드가 복잡해보일 수 있다는 문제점을 알게 되었다.

0개의 댓글