타입스크립트가 실행되는 공간과 실제 코드가 진행되는 런타입 공간은 엄연히 다르니 그것을 잘 구분해야한다는 이야기.
아래의 예시 코드를 통해서 그 이해를 도울 수 있다.
interface Cylinder {
radius: number;
height: number;
}
const Cylinder = () => {}
if(shape instanceof Cylender){
어쩌고저쩌고
}
위의 코드에서 instanceof Cylender는 얼핏 보면 맞는 말로 보일 수 있다.
허나 instanceof는 자바스크립트의 런타임 연산자이고, 값에 대해서 연산을 한다. 따라서 instanceof Cylinder는 타입이 아니라 값인 함수 Cylinder를 참조한다.
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 즉, 인스턴스의 타입이라는 의미