[TypeScript] 3. Functions

wonnie1224·2022년 8월 3일
0

TypeScript

목록 보기
3/4

✏️ 화살표 함수

let func = (arg1, arg2, ...argN) => expression
//아래 함수 표기와 같은 내용임
let func = function(arg1, arg2, ...argN) {
    return expression;
};

📌 3.0 Call Signatuers

function add(a: number, b: number) {
    return a + b
}
// 화살표 함수로 나타내면
const add = (a: number, b: number) => a + b
  • call signature : 함수 위에 마우스를 올렸을 때 보게 되는 것 (밑에 드래그된 부분)

  • 함수의 인자(arguments) 타입 & 리턴 타입을 알려줌

  • 함수를 구현하기 전에 미리 함수의 타입을 지정해놓을 수 있음!

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

const add: Add = (a, b) => a + b;   // a와 b의 타입이 number라는 걸 안 알려줘도 됨
// add 함수의 타입이 Add이고, 위에서 Add 타입을 선언해놨기 때문!

📌 3.1 Overloading

  • 오버로딩 : 함수가 #개의 call signatures를 가지고 있을 때 발생함
type Add = {
    (a: number, b: number): number
    (a: number, b: string): number
}
const add: Add = (a, b) => {
    if(typeof b === "string") return a  // b의 타입이 string이면 a(number 타입)를 리턴
    return a + b    // b의 타입이 string이 아니면 a+b(number 타입)를 리턴
}

1. 다른 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)
    }
}

2. call signature & 파라미터 개수가 모두 다른 경우

  • 파라미터 개수가 다를 때, 추가적인 파라미터 (파라미터 c)는 옵션이다(있을수도 있고, 없을수도 있음)
    -> 타입을 알려줘야하고, 이 파라미터가 선택사항이라는 걸 알려줘야함
type Add = {
    (a: number, b: number): number
    (a: number, b: number, c: number): number,
}

const add: Add = (a, b, c?: number) => {
    if(c) return a + b + c  // c가 있으면 a + b + c를 리턴해라
    return a + b // c가 없으면 a + b를 리턴해라
}

console.log(add(1, 2))
console.log(add(1, 2, 3))

📌 3.2 Polymorphism

🔍 뜻?
many(poly) + structure(morphos)
여러가지 다른 구조, 형태를 가진 함수들..

🔍 실습 : 인수로 concrete type(number/string/boolean 등)으로 이루어져있는 배열을 전달받고, 배열의 각 요소를 하나씩 출력하는 함수 만들기

  1. 함수의 call signature 만들자
    인수 : number 타입 배열, 아무것도 리턴 안 하니까 리턴 타입 : void
    이런식으로 끝도 없이 인수 타입 추가하면 비효율적임 => 제네릭 사용!
type SuperPrint = {
    (arr: number[]):void
    (arr: string[]):void
}
  • concrete type : 우리가 전부터 봐왔던 타입
  • generic : type의 placeholder 같은 거임
    -- concrete type 대신 쓰고 typescript가 그 타입이 뭔지 유추해서 함수를 사용하는 것
    -- call signature를 작성할 때 인수에 들어올 확실한 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])
superPrint(["a", "b", "c"])
superPrint([1, 2, true, false])
  • 타입스크립트는 placeholder의 타입을 인식하고, 함수의 call signature를 만들어 줌 -> 보호해준다

📌 3.3 Generics Recap

  • 제네릭은 내가 요구한대로 함수의 call signature를 생성해주는 도구이다

1. typescript에게 이 call signature가 generic을 사용한다고 알려주기

  • 제네릭 이름 적기 ex) <T>, <M> 많이 사용

2. 어디에서 해당 제네릭을 사용할 건지 알려주기

ex) 함수의 몇 번째 인자, 리턴 타입...

  • 타입스크립트는 제네릭이 처음 사용되는 지점을 기반으로 이 타입이 먼지 알게 됨
type SuperPrint = <T,M>(a: T[], b: M) => T

const superPrint : SuperPrint = (a) => a[0]

const a = superPrint([1, 2, 3, 4],"x")
const b = superPrint([true, false, true], 1)
const c = superPrint(["a", "b", "c"], false)
const d = superPrint([1, 2, true, false, "hello"], [])


📌 3.4 Generic을 사용하는 경우 알아보기

1. type 생성

function superPrint<T>(a: T[]){
  return a[0]
}

const a = superPrint([1, 2, 3, 4])
const b = superPrint([true, false, true])
const c = superPrint(["a", "b", "c"])
const d = superPrint([1, 2, true, false])

2. type 확장(type 재사용)

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

type NicoExtra = {
    favFood: string
}

type NicoPlayer = Player<NicoExtra>

const nico: NicoPlayer = {
    name: "Nico",
    extraInfo: {
        favFood: "kimchi"
    }
}
// extraInfo가 없는 경우 제네릭 타입 = null 타입으로 함
const lynn: Player<null> = {
    name: "Lynn",
    extraInfo: null
}
  • 타입스크립트의 기본적인 타입은 제네릭으로 만들어져 있음
profile
안녕하세요😊 컴퓨터비전을 공부하고 있습니다 🙌

0개의 댓글