개발/타입스크립트

TypeScript로 블록체인 만들기(2)

TTOLBE 2022. 12. 28. 15:50

Functions

이 글은 노마드 코더의 타입스크립트 무료 강의를 보고 노트 정리를 한 글입니다.
강의링크

3.0 Call Signatures

call signature는 함수의 타입을 정하는걸 의미한다. call signature를 호출하는 방법은 아래와 같다.


type Add=(a:number, b:number)=>number

두 인자를 숫자로 받고 결과값으로 숫자를 리턴한다는 의미를 갖는다.


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

call signature를 사용하면 a,b가 숫자 타입이라고 명시할 필요가 없다.

3.1 Overloading

오버로딩은 외부 라이브러리에 많이 사용 된다. 패키지나 라이브러리는 오버로딩을 많이 사용하기 때문에 모양 정도는 알아두는게 좋다.


type Add1=(a:number, b:number)=>number


type Add2={
  (a:number, b:number):number
}

위 두 타입은 동일한 의미를 갖는다. 아래의 방식이 존재하는 이유는 오버로딩 떄문이다. 오버로딩은 함수가 여러개의 다른 call signature를 가질 때 발생한다.


type Add={
  (a:number, b:number):number
  (a:number, b:string):number
}

위와 같은 상태가 오버로딩이다. 함수의 타입이 두가지 일 수 있단 걸 의미한다. 이런 상황에서 아래와 같은 함수는 에러가 난다.


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

파라미터 b가 숫자인지 문자열인지 명시해주지 않았기 때문이다.


 const add:Add = (a,b)=>{
  if(typeof b==="string") return a;
  return a+b;
 }

위와 같이 작성해주면 오류가 나지 않는다.

실제 Next.js에서 오버로딩이 사용되는 예제를 보자.


Router.push({
  path:"/home",
  state:1
})

Router.push("/home)

Router.push 함수는 오브젝트, 또는 스트링을 인자로 받을 수 있다.


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)
  }
}

call signiture 마다 파라미터의 갯수가 다른 경우도 있다.


type Add={
  (a:number, b:number):number
  (a:number, b:number, c:number):number
}

const add:Add = (a,b,c) =>{
  return a+b
}

위처럼 call signature를 작성하고 나서 위의 함수를 작성하면 오류가 난다. c가 optional 하단 걸 명시해야만 한다.


const add:Add=(a,b,c?:number)=>{
  if(c) return a+b+c
  return a+b
}

3.2 Polymorphism

polymorphism 이란 여러 다른 구조물이란 의미다. 어떤 배열이든 받아서 각 요소를 프린트하는 함수를 만들어보자.


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

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

위의 함수는 숫자 배열 일때만 작동한다. call signature에 여러 배열 종류를 추가 해줄 수 있지만 너무 비효율적이다.

우리가 지금까지 살펴본 number, string등은 concrete 타입이다. 이번에는 generic 타입을 사용해보자. generic이란 placeholder 같은 타입이다. call signature 에서 그 자리에 들어올 정확한 타입을 모를 때 사용한다.


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

위와 같이 맨 앞에 <>안에 generic의 명칭을 쓰고 타입의 자리에 그 명칭을 적으면, 이제 SuperPrint 타입의 함수는 어떤 배열이든지 받아올수 있게 된다. 위 타입을 사용하면 Generic이란 값은 숫자로만 이루어진 배열에는 number 타입으로 변하고, string으로 이루어진 배열에서는 string 타입으로 변한다.