- 타입스크립트 컴파일러를 실행(tsc) TS -> JS
- 단독으로 실행할 수 있는 타입스크립트 서버(tsserver)
- 타입스크립트 언어서비스를 적극 활용해야한다.
- 타입스크립트가 동작을 어떻게 모델링 하는지 알기 위해서 타입선언파일을 찾아본다.
타입스크립트에서 타입은 '할당 가능한 값들의 집합' 이라고 생각하면 된다. 예를 들어 모든 숫자의 집합은 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
언뜻 보기에 Person
과 LifeSpan
인터페이스는 공통으로 가지는 속성이 없기때문에, PersonSpan
타입을 공집합(never)로 예상하기 쉽습니다. 그러나 타입연산자는 인터페이스의 속성이 아닌, 값의 집합(타입의 범위)에 적용되기 때문에 추가적인 속성을 가지는 값도 여전히 그 타입에 속합니다.
따라서 Person
과 LifeSpan
을 모두 가지는 값들의 집합이 인터섹션 타입에 속하게 됩니다.
당연히 앞의 세가지보다 더 많은 속성을 가지는 값도 PersonSpan
타입에 속합니다.
type PersonOrSpan = Person | LifeSpan
type PersonOrSpanKey = keyof (Person | LifeSpan) // never
PersonOrSpanKey
가 never
타입이 나오는 것은 약간 당황스럽다.
이유는 유니온 타입에 속하는 값들이 공통적인 키가 없기 때문에 공집합(never
) 나와야한다
keyof
는 분배법칙을 이용할 수 잇는데, 아래와 동일하다. 공통으로 가진 키가 없으므로 never
가 된다.
type PersonOrSpanKey = keyof Person & keyof LifeSpan // never
타입이 값들의 집합이라는 관점에서 extends
의 의미는 '~의 부분집합'이라는 의미로 해석하면 수월하다.
function getKey<K extends string>(val: any, key:K) {
//..
}
위 함수에서 K
는 string
을 상속한다는 의미로 해석하면 이해가 어렵고, string
의 부분집합 이라는 의미로 해석하면 쉽다.
- 타입을 값의 집합으로 생각하면 이해하기 편하다.
- 한객체의 추가적인 속성이 타입 선언에 언급되지 않더라도 그 타입에 속할 수 있다.
- 타입연산은 속성이 아닌 집합의 범위에 적용된다.