TypeScript -5-

mh·2022년 5월 3일
0

TypeScript

목록 보기
5/17
post-thumbnail

Photo by Mathilde Normandeau on Unsplash

Polymorphism (다형성)

그리스어: poly
many : several : much : multi-

polygon(다각형) : poly 많은 + gon 각도

morpho-
"form, structure"

many(poly) structure(morphos)
여러가지 다른 구조들

ex) 여태까지 경험해본 다형성들

  • 함수는 여러가지 다른 모양(형태)를 가지고 있음
  • 함수는 2-3개의 다른 parameter를 가질 수 있음
  • string이나 object를 첫번째 parameter로 가질 수 있음

case) 타입과 상관없이 배열을 받고, 배열의 요소를 하나씩 print 해주는 함수

  • call signature 작성
  • arr를 받을건데 number요소를 가진 arr
type SuperPrint = {
    (arr: number[]):void
}
  • 아무것도 리턴하지 않으니 void
  • superPrint 함수 작성
  • :SuperPrint 로 타입 지정
type SuperPrint = {
    (arr: number[]):void
}

const superPrint: SuperPrint = (arr) => {
    arr.forEach(i => console.log(i))
}
  • arr를 인자로 받고 각 요소마다 로그를 출력해주는 함수
type SuperPrint = {
    (arr: number[]):void
}

const superPrint: SuperPrint = (arr) => {
    arr.forEach(i => console.log(i))
}
  • boolean 타입을 받을 수 있게 call signature 추가
type SuperPrint = {
    (arr: number[]):void
    (arr: boolean[]):void
}

const superPrint: SuperPrint = (arr) => {
    arr.forEach(i => console.log(i))
}
  • 함수 실행시켜보기
superPrint([1,2,3,4])
superPrint([true,true,false])
superPrint(["a","b","c"])

  • 문자열을 넣을려면 다시 SuperPrint에 (arr: string[]):void를 작성해야 하는가? -> 다른 방법이 있음 -> 다형성 활용

Generic

타입스크립트에게 더 나은 방법으로 얘기하기

(arr: number[]):void
(arr: boolean[]):void
(arr: string[]):void
  • concreate type : number, string, boolean, void, unknown ...
  • concreate type 대신 다른걸 써보기

generic?

  • generic 은 type을 위한 placeholder 같은 것
  • TS가 그걸 보고 추론해서 함수를 사용
type SuperPrint = {
    (arr: number[]):void
    (arr: boolean[]):void
    (arr: string[]):void
}

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

superPrint([1,2,3,4])
superPrint([true,true,false])
superPrint(["a","b","c"])
  • call signature 가 3개
  • superPrint([1, 2, true, false]) 이런식으로 받으려하면 오버로드가 없기때문에 작동 안됨
  • 하지만 위에서 말한 타입과 상관없이 배열을 받고, 배열의 요소를 하나씩 print 해주는 함수 를 작성하려면?
type SuperPrint = {
    (arr: number[]):void
    (arr: boolean[]):void
    (arr: string[]):void
    (arr: (number | boolean)[]):void
}
  • 이런식으로 작성한다면 가능성을 모두 조합해야하기 때문에 힘듦

  • call signature를 작성할때, call signiture안에 들어올 타입이 여러가지이지만 뭐가 올지 모를때

  • 함수를 작성할때는 concrete type을 이용해야겠지만 call signature를 작성할때는 concrete type이 무엇이 올지 모를경우가 있음

  • 이런 경우에 generic 사용

generic 사용하기

  1. TS에게 generic을 사용한다고 알려주기
  • <>를 열고 generic 이름 짓기
  • Generic, Placeholder, Potato, Pizza...
  • T, V (실제 라이브러리에서 많이사용)
  • 무수한 라이브러리의 요청.. 아무이름이나 해도 됨
  • 여기선 <TypePlaceholder>로 사용
type SuperPrint = {
    <TypePlaceholder>(arr: number[]):void
}
  • 이것이 call signature가 generic을 받는다는걸 알려주는 방법
  • number[]를 TypePlaceholder로 바꿔주기
type SuperPrint = {
    <TypePlaceholder>(arr: TypePlaceholder[]):void
}
  • 여기서 TS는 superPrint안의 [1,2,3,4] 값을 PlaceHolder로 보고 유추해서 숫자배열로 이루어진 call signature 라는 결론을 내림

  • Placeholder 대신 타입스크립트가 발견한 타입으로 바꿔줌

  • 이런 복잡한 값도 call signature를 따로 작성하지 않고 편하게 작업할 수 있음

  • 제네릭은 여전히 함수에 타입을 입력하는걸 허용

return 값에도 사용해보기

  • superPrint의 리턴값 바꾸기
  • 배열을 받고 그 배열의 첫번째 요소를 리턴하게 만들기
const superPrint: SuperPrint = (arr) => arr[0];
  • SuperPrint타입의 리턴타입 void를 TypePlaceholder로 바꾸기 (리턴하는 함수로 바뀌었기 때문)
type SuperPrint = {
    <TypePlaceholder>(arr: TypePlaceholder[]):TypePlaceholder
}

  • placeholder 중 하나의 값을 리턴하도록 만듦
  • 리턴값 받기
const a = superPrint([1,2,3,4])
const b = superPrint([true,true,false])
const c = superPrint(["a","b","c"])
const d = superPrint([1,"ab",true,"123"])


  • 이 superPrint 함수는 다양한 형태를 가지고 있음
  • boolean[], string[], number[] , (boolean | stirng | number)[] 를 받을 수 있음
  • 이것이 바로 다형성
type SuperType = {
    <T>(arr: T[]):T
}
  • 이런 형태의 generic을 라이브러리에서 마주칠 일이 많음

정리

  • call signature에 어떤 타입이 들어올지 알 수 없을때 generic 사용
  • generic은 TS를 위한 placeholder
  • generic은 타입스크립트에게 타입을 유추하도록 placeholder를 이용해 알려주는 것
  • TS는 함수를 실행할때 들어온 값을 보고 받을 인자의 타입, 리턴값의 타입을 유추하여 placeholder 대신 집어넣음
  • 다양한 타입이 들어올때 모든 조합을 생각해서 call signature를 작성하지 않아도 됨
  • 이것말고도 React에서 사용하는 다른 방법들도 있음
profile
🤪🤪🤪🤪🤪

0개의 댓글