TypeScript -4-

mh·2022년 5월 3일
0

TypeScript

목록 보기
4/17
post-thumbnail

Photo by Maxim Potkin ❄ on Unsplash

Call signatures

타입규칙을 지정하는 방법

function add(a, b)

  • 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 만들어보기

//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로 함수를 보내게 될때 어떻게 작동하는지(인자는 어떤걸 받아야되고, 반환값은 어떤타입이어야 하는지) 알려줘야 됨 -> 실수 방지

Overloading

  • 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
};
  • 이런방법이 존재하는 이유 -> overloading 때문
  • Overloading은 함수가 서로 다른 여러개의 Call signature를 가지고 있을때 발생됨

case1 바보같지만 많이 일어나는 일

// type Add = (a:number, b:number) => number;
type Add = {
    (a:number, b:number) : number //1번 시그니쳐
    (a:number, b:string) : number //2번 시그니쳐
};
  • 이렇게 되면 Add라는 함수는 1번 시그니쳐 로 부를 수도 있고 2번 시그니쳐 로 부를 수도 있음
  • 타입스크립트는 잘못됨을 감지
a:number a:numberb:number b:string
  • b는 number도 될수 있고 string이 될 수도 있기때문에 TS가 감지
  • TS曰: b는 string 혹은 number이기 때문에 string과 number는 결합할 수 없다.
  • typeof를 사용해 조건을 정해주면 됨
  • b가 문자열일때 a를 리턴
  • 아니면 a + b를 리턴
const add:Add = (a, b) => {
    if(typeof b === "string") return a
    return a + b      
}
  • Overloading : call signature가 여러개 있는 함수 혹은 call signature가 있는 함수

case2 실제 개발할때 마주치는 일

  • 자주쓰는 라이브러리에 함수가 있다 가정 (Next.js)
  • 이 함수는 string을 보낼 수 있거나 configuration 같은 객체를 보낼 수 있게 혀용되어있음

ex) Next.js에서는 Router를 이용해 페이지를 바꿀 수 있음

Router.push("/home")
  • 라우터에 문자열을 넣어서 원하는 페이지로 이동가능
  • 혹은 객체 형식으로 보내 줄 수 있음
Router.push({
  path: "/home",
  state : 1
})
  • 함수를 사용하는 방식(call signature)가 2가지 이지만 오류없이 잘 작동함
  • Overloading의 실제 사용 예시
  • Router Overloading 구조 만들어 보기
  1. Push 타입 지정
type Push = {
    (path:string):void //아무것도 반환하지 않으니 void
    (object)
}
  1. Config 타입 지정
type Config = {
    path:string,
    state: object
}

type Push = {
    (path:string):void
    (object)
}
  1. Push의 object를 config로 대체
type Config = {
    path:string,
    state: object
}

type Push = {
    (path:string):void
    (config: Config):void
}
  1. Push 함수 사용하기
type Config = {
    path:string,
    state: object
}

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

const push:Push = (config) => {}

TS: config는 string이나 Config 객체를 받을 수 있음
그러므로 조건문으로 string을 받았을때와 config를 받았을때를 나눠줘야 함

  1. 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
}
  • c는 선택사항이라는 것을 알려주고, 추가적으로 타입을 줌
const add:Add  = (a,b,c?:number) => {
    if(c) return a + b + c
    return a+ b
}
  • c가 있을때는 a + b + c 를 반환, 없다면 a + b만 반환
add(1,2) //3
add(1,2,3) //6


정리

  • call signature : 함수를 구현하기전 타입지정과 코드를 분리할 수 있고, 나만의 타입을 만들 수 있음, 함수가 어떻게 작동되야 하는지(인자로 어떤 타입이 와야하는가, return은 어떤타입이어야 하는가) 서술되어있음
  • Overloading : 여러개의 call signature 가 있는 함수, 가지고 있는 call signature마다 여러방법으로 함수를 사용 가능, call signature마다 받는 인수의 형태나 갯수가 다를 수 있음, 이를 이용해 한가지 함수로 기능을 사용하거나 값을 보낼 수 있음 ex) Next.js, Express.js 의 Router 함수
profile
🤪🤪🤪🤪🤪

0개의 댓글