개발/이펙티브 타입스크립트

[이펙티브 타입스크립트+8] 타입 공간과 값 공간의 심벌 구분

Junghyun Kim 2021. 8. 4. 22:33
반응형

https://www.typescriptlang.org/play

2장 타입스크립트의 타입 시스템
아이템 8 | 타입 공간과 값 공간의 심벌 구분하기

3줄 요약
1. 타입스크립트에서는 타입의 공간과 값의 공간이 분리되어있다.
2. 타입스크립트 코드를 읽을 때 타입인지 값인지 구분하는 방법을 터득해야 한다.
3. 클래스(생성자 함수)의 타입은 typeof 클래스이고, 인스턴스의 타입은 클래스이다.

참고) 이펙티브 타입스크립트는 타입스크립트의 기본 그 이상을 다룹니다.


타입스크립트에서는 값의 공간(context)와 타입의 공간(context)가 다릅니다.
따라서, 똑같은 이름의 식별자(책에서는 심볼)가 각각의 공간에서 각자 존재할 수 있습니다.
(그렇다고 해서 이렇게 똑같은 이름으로 쓰는 것은 권장하지 않습니다. 본인뿐만 아니라 같이 개발하는 동료까지 헷갈리게 할 수 있습니다.)

똑같은 이름의 타입과 변수.

이렇게 똑같의 이름의 식별자가 각각의 공간에 존재할 수 있는 것처럼 몇몇 똑같은 이름의 연산자들은 타입의 공간과 값의 공간에 각자 존재합니다.
typeof가 그 예시입니다. 값의 관점에서는 typeof는 런타임에 식별자의 타입을 가리키는 문자열은 반환하는 연산자입니다.
그러나 타입의 관점에서는 타입스크립트 타입으로 반환합니다.

타입 공간에서의 typeof.
값의 공간에서의 typeof. "object"

타입스크립트에서 interface나 type의 경우에는 타입의 공간에서만 존재합니다. 따라서, 자바스크립트로 트랜스파일을 하게 되면 사라지게 됩니다. (직접 확인해보고 싶으면 이 글의 첫 이미지에 나오는 것처럼 타입스크립트 플레이그라운드에서 확인할 수 있습니다.)

그러나 타입의 공간과 값의 공간에 동시에 존재하는 것 또한 있습니다. 그중 하나가 바로 class입니다.
자 그러면 이 class의 타입에 대해 한번 살펴보겠습니다.

먼저 클래스를 정의를 하면 값의 공간에 이 클래스의 타입은 어떻게 될까요?
클래스는 내부적으로 함수입니다. 따라서 "function"입니다.
그러면 이 Stone이라는 클래스 혹은 내부적으로 생성자 함수를 이용하여 만든 인스턴스의 타입은 어떻게 될까요?
자바스크립트에서는 object가 됩니다.

클래스 자체의 타입은 function. 클래스로 만들어낸 인스턴스의 타입은 object.

값의 공간에서 이야기를 했으니 이번에는 타입의 공간에서 이야기를 해보겠습니다.
타입의 공간에서 Stone 클래스의 타입은 무엇일까요?

typeof Stone의 타입은 typeof Stone...?

의미심장합니다. "Stone 클래스야, 너의 타입은 뭐니?"라고 물었더니 "저는 Stone 클래스 타입인데요"라고 말하는 것 같습니다.
뭔가 찜찜하지만 본인이 그렇다고 하면 그렇게 받아들여야 합니다. 이제부터 Stone 클래스, 즉 클래스의 생성자 함수의 타입은 typeof Stone입니다.
인스턴스를 생성하고 해당 인스턴스의 타입을 한 번 살펴보겠습니다.

Stone의 인스턴스의 타입은 Stone.

이제야 말이 통하는 녀석을 만난 것 같습니다. 이 인스턴스의 타입은 Stone입니다.
그러면 정리를 해보겠습니다.
클래스의 타입은 typeof 클래스이며, 인스턴스의 타입은 클래스입니다.
typeof 클래스는 또한 생성자 함수를 나타낸다는 것을 기억해야 합니다.

 

일반 함수의 타입은 보통 아래와 같이 생겼습니다.

doSomething 함수의 타입은 (input: number) => string.

만일 해당 함수의 리턴 타입을 알고 싶다면 어떻게 하면 될까요?
바로 ReturnType이라는 유틸리티 타입을 이용하면 됩니다.

리턴 타입이 string으로 추론되었다.

doSomething 함수의 리턴 값이 "good"이어서 string 타입으로 추론된 것을 확인할 수 있습니다.

이와 유사하게 typeof 클래스를 이용하여 클래스의 인스턴스 타입을 얻을 수 있습니다.
InstanceType이라는 유틸리티 타입을 이용하면 됩니다.

인스턴스의 타입이 Stone으로 추론되었다.

흥미로운 것은 InstanecType의 문서에 나오는 제네릭의 타입입니다.
에디터에서 확인했던 클래스 생성자 함수의 타입은 단순히 'typeof 클래스'이었습니다만 문서에서는 더 자세히 나옵니다.

abstract new (...args: any) => any. 에디터 상에서 InstanceType을 타고 들어가면 더 자세한 타입이 나옵니다.

숨겨져 있어서 자세히 알지 못했던 생성자 함수의 타입은 이렇게 생겼습니다.

 

Materials From
1. <이펙티브 타입스크립트>(댄 밴더캄 지음, 장원호 옮김, 인사이트 2021)
2. 타입스크립트 공식 홈페이지 | https://www.typescriptlang.org/

 

Typed JavaScript at Any Scale.

TypeScript extends JavaScript by adding types to the language. TypeScript speeds up your development experience by catching errors and providing fixes before you even run your code.

www.typescriptlang.org

 

반응형