이펙티브 타입스크립트 2-8 타입 공간과 값 공간의 심벌 구분하기

이승훈·2023년 6월 17일
0
post-thumbnail

타입스크립트가 실행되는 공간과 실제 코드가 진행되는 런타입 공간은 엄연히 다르니 그것을 잘 구분해야한다는 이야기.

공간 구분을 해야하는 이유

아래의 예시 코드를 통해서 그 이해를 도울 수 있다.

interface Cylinder {
	radius: number;
  	height: number;
}
  

const Cylinder = () => {}

if(shape instanceof Cylender){
	어쩌고저쩌고
}

위의 코드에서 instanceof Cylender는 얼핏 보면 맞는 말로 보일 수 있다.
허나 instanceof는 자바스크립트의 런타임 연산자이고, 값에 대해서 연산을 한다. 따라서 instanceof Cylinder는 타입이 아니라 값인 함수 Cylinder를 참조한다.

class와 enum

class와 enum은 상황에 따라 타입공간과 값 공간에서 모두 사용이 가능하다.
아래의 예제에서 Cylinder는 타입으로 쓰인 예제이다.

class Cylinder {
	radius = 1;
	height = 1;
}

function calculateVolume(shape: unknown){
	if(shape instanceof Cylinder){
    	shape  <- 여기서의 타입은 Cylinder
        shape.radius  <- 여기서의 타입은 number
    }
}

타입의 관점과 값의 관점

interface Person {
	first: string;
  	last: string;
}

const p: Person = {fisrt: 'Jane', last: 'Sonata'}

function email(p:Person, subject:string, body:string):Response{
  ...
}

type T1 = typeof p; <- 여기서 타입은 Person
type T2 = typeof email; <- 여기서 타입은 (p:Person, subject:string, body:string) => Response

const v1 = typeof p; <- 여기서 값은 'object'
const v2 = typeof email <- 여기서 값은 'function'

타입의 관점에서 typeof는 값을 읽어서 타입스크립트 타입을 반환한다.
값의 관점에서 typeof는 자바스크립트 런타임의 typeof 연산자가 된다.

타입스크립트의 타입종류는 무수히 많다.
허나 자바스크립트는 예로부터 지금까지 단 6개만이 존재한다.

(string, number, boolean, function, undefined, object)

위의 예제에서 보여줬듯 class는 값과 타입 두가지로 모두 사용이 가능하다.
따라서 클래스에 대한 typeof는 상황에 따라 다르게 동작한다.

const v = typeof Cylinder; <- 값이 'function'
type T = typeof Cylinder; <- 타입이 typeof Cylinder

값에서의 typeof야 클래스가 원래 javascript에서는 함수니까 'function'이 나오는게 당연한거고,
두번째는 뭔가 싶을 수 있다.
지금도 뭔가 싶긴한데 중요한건 타입의 관점에서 typeof Cylinder가 인스턴스의 타입이 아니라는 점이다.

declare let fn: T;
const c = new fn(); <- 여기서 타입은 Cylinder 이게 인스턴스의 타입

만일 클래스의 인스턴스의 타입을 알고 싶다면 InstanceType이라는 유틸리티 타입을 사용하여 알 수 있다.

type C = InstanceType<typeof Cylinder>;
 <- 여기서도 타입이 Cylinder 즉, 인스턴스의 타입이라는 의미
profile
Beyond the wall

0개의 댓글