본문 바로가기
타입스크립트

타입스크립트5. 함수의 call signatures

by 혀닙 2022. 5. 15.

목차

  1. call signatures
  2. 오버로딩(overloading)
  3. 다형증(polymorphism)
  4. generic

 

 

 

1. call signatures란?

함수 위에 마우스를 올렸을 때 보게 되는 것

함수를 어떻게 호출해야 하는 지와 함수가 반환하는 데이터의 유형도 보여줌

 

 

타입스크립트를 사용해서 콜 시그니처를 작성하면

  1. 프로그램을 디자인 하면서 데이터의 유형을 미리 생각하고
  2. 코드를 구현

할 수 있게 된다.

 

 

type Add = (a: number, b:number) => number;	// 함수를 작성하기 전, 함수의 동작을 미리 작성해두면

const add: Add = (a,b) => a + b	//데이터 유형을 지정해주지 않아도, TS가 콜 시그니쳐를 추론함

 

 

2. 오버로딩(overloading)

  • 함수가 서로 다른 여러개의 call signature를 가지고 있을 때 발생
type Config = {
	path: string,
    state: object
}

type Push = {
	(path:string): void
    (config: Config): void
}


const push:Push = (config) => {
	if(typeof config === 'string') {console.log(config)}
    else {
    	console.log(config.path, config.state)
    }
}

 

 

  • 다수의 콜시그니쳐에서 매개변수의 갯수가 다른 경우
type Add = {
	(a: number, b: number) : number
	(a: number, b: number, c: number) : number,
}


const add: Add = (a,b,c?:number) => {	//특정 매개변수는 선택사항이라는 점과 매개변수의 데이터 유형을 TS에게 알려줘야 한다.
	if(c) return a + b + c
    return a + b
}

 

 

3. 다형성(polymorphism)

영어에서 poly는 many, several, much, multi라는 뜻을 가진 접두어이다.

morphos는 form, structure란 뜻이다.

즉, 여러개의 다른 형태들, 모양들, 구조들이란 뜻이다.

 

함수는 다른 2-3개의 매개변수를 가질 수 있고.

문자열이나 객체를 인자값으로 가질 수 있다.

 

 

매개변수로 숫자로 이루어져있는 배열을 받고 배열의 요소를 하나하나씩 출력하는 함수를 생성해보자

type SuperPrint = {
	(arr: number[]): void
    (arr: boolean[]): void
    (arr: string[]): void
}

const superPrint = SuperPrint = (arr) => {
	arr.forEach(i => console.log(i)
}


superPrint([1,2,3,4])
superPrint([true, false, true, false])
superPrint(['1,','2','3'])


// 만약 아래와 같이 함수를 호출한다면?
superPrint([1,2,true,false])
// 콜시그니쳐가 없기 때문에 에러가 발생할 것이다

 

 

 

아래와 같이 콜 시그니처를 작성해주어야 한다.

type SuperPrint = {
	(arr: number|boolean[]): void

}


const superPrint = SuperPrint = (arr) => {
	arr.forEach(i => console.log(i)
}


superPrint([1,2,true,false])	// ok


하지만 만약 아래와 같이 호출하고 싶다면?
superPrint([1,2,true,'not ok'])	// call signature가 없게 때문에 다시 같은 상황이 발생하게 된다.

 

 

따라서 이와 같은 상황을 피하기 위해서 알아두면 좋은 개념이 generic이다.

 

 

 

generic type이란?

  • 타입의 placeholder 같은 개념
  • 변수나 인수에 데이터의 유형을 정해주는 concrete와는 달리 데이터 유형을 정해주지 않고, 그 타입에 들어온 유형을 보고 데이터 타입을 유추
  • 콜 시그니쳐 작성 시, 인자값으로 들어올 데이터의 유형을 모를 때 generic 사용

 

 

제네릭 타입을 사용하면 타입스크립트가 인자로 들어온 값을 보고 유추하여 콜 시그니쳐를 생성해준다.

 

type SuperPrint = {
	<TypePlaceholder>(arr:TypePlaceholder[]): void
}

const superPrint = SuperPrint = (arr) => {
	arr.forEach(i => console.log(i)
}


superPrint([1,2,3,4])
superPrint([true, false, true, false])
superPrint(['1,','2','3'])
superPrint([1,2,true,false])
superPrint([1,2,true,'ok'])

 

 

 

<참고> concrete type

  • string
  • number
  • boolean
  • void
  • unknown

 

 

 

type Player<E> = {
	name: string
	extraInfo: E
}

type SonExtra = {

}

type SonPlayer = Player<{ favFood: string }>

const son: SonPlayer = {
	name: 'son',
    extraInfo: {
    	favFood: 'ice-cream'
    }
}


const kane: Plyaer<null> = {
	name: 'kane',
    extraInfo: null
}

 

댓글