Photo by Maxim Potkin ❄ on Unsplash
function add(a, b)
function add(a:number, b:number) {
return a + b
}
const add = (a:number, b:number) => a + b
(a: number, b:number) => number
이것이 함수의 call signature//call signature
type Add = (a:number, b:number) => number;
//function
const add:Add = (a, b) => a + b
이렇게 하면 함수 인자나 인자뒤에 :number 이런식으로 일일히 타입을 지정해주지 않아도 타입규칙이 정해짐
타입스크립트에서 add의 타입을 알기 때문
안쪽의 a, b들의 타입도 정해지기 때문에 일일히 정할 필요 없음
함수작성시 정해진 call signature대로 리턴값이 잘못된 경우 알려줌
어떤 함수를 구현하기 전에 나만의 타입을 만들 수 있고, 어떻게 작동해야하는지 서술해둘 수 있음
첫번째로 타입을 생각하게 됨 -> 함수의 타입을 먼저 설명 -> 코드 구현
타입을 각각 지정하지 않아도 됨 -> 함수의 타입지정과 코드작성을 분리해서 구현가능
엄청 많이 씀
TS로 리액트에서 props로 함수를 보내게 될때 어떻게 작동하는지(인자는 어떤걸 받아야되고, 반환값은 어떤타입이어야 하는지) 알려줘야 됨 -> 실수 방지
function overloading , method overloading 다양하게 불림
실제로 오버로딩된 함수를 직접 작성하진 않음 대부분 외부 라이브러리를 사용
이 외부 라이브러리들이 오버로딩을 많이 사용함
type Add = (a:number, b:number) => number;
// const add:Add = (a, b) => a + b
const add:Add = (a, b) => a + b
(a:number, b:number) => number
-> call signature : 타입스크립트에게 이 함수가 어떻게 호출되어야 하는지 설명해주는 부분
(a:number, b:number) => number
이런 방법은 call signature 만드는 방법중에 비교적 간단하게 만드는 방법임
길게 작성해보기
// type Add = (a:number, b:number) => number;
type Add = {
(a:number, b:number) : number
};
// type Add = (a:number, b:number) => number;
type Add = {
(a:number, b:number) : number //1번 시그니쳐
(a:number, b:string) : number //2번 시그니쳐
};
1번 시그니쳐
로 부를 수도 있고 2번 시그니쳐
로 부를 수도 있음a:number a:number | b:number b:string |
---|---|
![]() | ![]() |
const add:Add = (a, b) => {
if(typeof b === "string") return a
return a + b
}
ex) Next.js에서는 Router를 이용해 페이지를 바꿀 수 있음
Router.push("/home")
Router.push({
path: "/home",
state : 1
})
type Push = {
(path:string):void //아무것도 반환하지 않으니 void
(object)
}
type Config = {
path:string,
state: object
}
type Push = {
(path:string):void
(object)
}
type Config = {
path:string,
state: object
}
type Push = {
(path:string):void
(config: Config):void
}
type Config = {
path:string,
state: object
}
type Push = {
(path:string):void
(config: Config):void
}
const push:Push = (config) => {}
TS: config는 string이나 Config 객체를 받을 수 있음
그러므로 조건문으로 string을 받았을때와 config를 받았을때를 나눠줘야 함
const push:Push = (config) => {
if(typeof config === "string") console.log(config)
else {
console.log(config.path, config.state);
}
}
config. 에서 path와 state를 사용할 수 있음
이런 방식은 패키지나 라이브러리를 디자인할때 많이 사용
실제로 오버로딩은 이런식으로 쓰임
type Add = {
(a:number, b:number, c:number): number;
}
a,b,c는 모두 number이고 반환값 또한 number임
서로 다른 call signauture에 parameter 갯수도 다를때
type Add = {
(a:number, b:number) : number
(a:number, b:number, c:number): number;
}
type Add = {
(a:number, b:number) : number
(a:number, b:number, c:number): number;
}
const add:Add = (a,b,c) => {
return a+ b
}
파라미터 갯수가 다르기 때문에 타입스크립트가 오류
(a:number, b:number)
(a:number, b:number, c:number)
파라미터 갯수가 다르다면 나머지 타입도 정해줘야 함
c는 옵션같은거임 c가 올 수도 있고 안 올수 있고, 지금은 타입도 모름
타입을 무엇일것 같다 라는 걸 정해줘야 함
c는 올수도 있고 안올수도 있고 c?
아마 number일 것이다 c?:number
type Add = {
(a:number, b:number) : number
(a:number, b:number, c:number): number;
}
const add:Add = (a,b,c?:number) => {
return a+ b
}
const add:Add = (a,b,c?:number) => {
if(c) return a + b + c
return a+ b
}
add(1,2) //3
add(1,2,3) //6