Skip to content

Instantly share code, notes, and snippets.

@DublinCity
Created June 30, 2022 16:36
Show Gist options
  • Save DublinCity/eb9128d0e293f53d13be21a59483f8e7 to your computer and use it in GitHub Desktop.
Save DublinCity/eb9128d0e293f53d13be21a59483f8e7 to your computer and use it in GitHub Desktop.
Item6-7: 편집기를 사용해 타입시스템 탐색하기, 타입을 값들의 집합이라고 생각하기

Item6: 편집기를 사용해 타입시스템 탐색하기

타입스크립트를 설치하면 다음 두가지를 할 수 있다

  • 타입스크립트 컴파일러를 실행(tsc) TS -> JS
  • 단독으로 실행할 수 있는 타입스크립트 서버(tsserver)

결론

  • 타입스크립트 언어서비스를 적극 활용해야한다.
  • 타입스크립트가 동작을 어떻게 모델링 하는지 알기 위해서 타입선언파일을 찾아본다.

Item7: 타입을 값들의 집합이라고 생각하기

타입스크립트에서 타입은 '할당 가능한 값들의 집합' 이라고 생각하면 된다. 예를 들어 모든 숫자의 집합은 number 이다.

타입의 범위에 따라 분류

  • never: 가장 작은 집합으로 아무것도 포함하지 않는 공집합
  • 리터럴 타입: 유닛타입이라고도 불리고 한가지 값만 포함하는 타입(ex. type A ='A' type Two = 2 , )
  • 유니온 타입: 값들의 집합을 두개 또는 세개 이상으로 묶는 타입(ex. type AB = A | B)
  • number, string: 범위가 무한대인 타입

타입의 연산

& 연산자는 두 타입의 값들의 인터섹션(교집합)을 계산

interface Person {
  name: string
}
interface LifeSpan {
  birth: Date;
  death: Date;
}

type PersonSpan  = Person & LifeSpan

언뜻 보기에 PersonLifeSpan 인터페이스는 공통으로 가지는 속성이 없기때문에, PersonSpan 타입을 공집합(never)로 예상하기 쉽습니다. 그러나 타입연산자는 인터페이스의 속성이 아닌, 값의 집합(타입의 범위)에 적용되기 때문에 추가적인 속성을 가지는 값도 여전히 그 타입에 속합니다.

따라서 PersonLifeSpan 을 모두 가지는 값들의 집합이 인터섹션 타입에 속하게 됩니다. 당연히 앞의 세가지보다 더 많은 속성을 가지는 값도 PersonSpan 타입에 속합니다.

| 연산자는 두 타입의 값들의 합집합을 계산

type PersonOrSpan = Person | LifeSpan
type PersonOrSpanKey = keyof (Person | LifeSpan) // never

PersonOrSpanKeynever 타입이 나오는 것은 약간 당황스럽다. 이유는 유니온 타입에 속하는 값들이 공통적인 키가 없기 때문에 공집합(never) 나와야한다

keyof 는 분배법칙을 이용할 수 잇는데, 아래와 동일하다. 공통으로 가진 키가 없으므로 never 가 된다.

type PersonOrSpanKey = keyof Person & keyof LifeSpan // never

extends

타입이 값들의 집합이라는 관점에서 extends 의 의미는 '~의 부분집합'이라는 의미로 해석하면 수월하다.

function getKey<K extends string>(val: any, key:K) {
  //..
}

위 함수에서 Kstring 을 상속한다는 의미로 해석하면 이해가 어렵고, string 의 부분집합 이라는 의미로 해석하면 쉽다.

결론

  • 타입을 값의 집합으로 생각하면 이해하기 편하다.
  • 한객체의 추가적인 속성이 타입 선언에 언급되지 않더라도 그 타입에 속할 수 있다.
  • 타입연산은 속성이 아닌 집합의 범위에 적용된다.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment