call signature는 함수의 이름, 인자의 이름과 타입, 리턴타입 등 함수의 입력과 출력의 정보를 말한다. 함수 이름에 마우스 커서를 올리면 볼 수도 있다.
아래와 같은 함수를 정의했다고 해보자.
function add(a: number, b: number): number {
return a + b
}
위 함수의 call signature는 다음과 같다.
function add(a: number, b: number): number
이 더하기 함수를 화살표 함수로 바꾸면 이렇게 된다.
const add(a: number, b: number) => a + b
화살표 함수를 사용했으므로 타입스크립트가 리턴 타입은 number라고 자동으로 추론한다.
위 함수의 call signature는 다음과 같다.
const add(a: number, b: number) => number
이런 함수의 call signature를 미리 만들어서 함수의 입력과 출력을 미리 정의하고 함수를 생성할 수 있다. call signature는 type을 이용하여 만들 수 있으며, 이후 함수를 생성할 때는 이 call signature를 타입으로 넣어주면 된다.
type Add = (a: number, b: number) => number
const add:Add = (a, b) => a + b
이미 call signature를 통해 인자 a, b의 타입이 number인 것과 리턴타입이 number인 것을 알고 있기 때문에 함수를 생성할 때 타입을 명시하지 않아도 된다.
overloading은 같은 이름의 함수가 여러 개의 call signature를 가지고 있도록 하는 것을 말한다. 예시로 이렇게 여러 개의 call signature를 가질 경우를 보자.
type Add = {
(a: number, b: number) : number,
(a: number, b: string) : number,
(a: number, b: number, c: number) : number
}
const add:Add = (a, b, c?) => {
if(typeof b === "string") return a
else if(c) return a + b + c
return a + b
}
코드에서 보듯이 3개의 call signature를 가지고 있다. 코드에서는 b의 타입이 number 또는 string이기 때문에 b의 타입에 따라 함수에서 실행할 코드를 따로 작성해주었고, c가 입력될 수도, 없을 수도 있기 때문에 c가 있는지 확인하고 그에 맞는 실행 코드를 작성하였다.
자바처럼 다음과 같이 작성하면 중복된 함수의 구현이라고 오류가 발생한다.
function add(a: number, b: number): number {
return a + b;
}
function add(a: number, b: string): number {
return a;
}
조금 복잡할 수도 있지만 위에서 적은 코드처럼 call signature를 이용하여 overloading을 구현하면 된다.