본문 바로가기
개발/TypeScript

런타임때에 사라지는 타입

by 안뇽! 2023. 1. 18.
반응형

  • 컴파일 : ts를 js로 변환하면서 코드를 만드는 과정, 타입체킹이 이루어짐
  • 런타임 : 응용프로그램이 실제로 동작되는 때

(참고 : 런타임과 컴파일타임 차이)

 

타입과 타입 연산자는 자바스크립트 변환 시점(컴파일)에 제거되기 때문에 런타임과 런타임 성능에 영향을 주지 않는다.

 

왼쪽은 test.ts, 오른쪽은 test.ts를 컴파일한 test.js다.

컴파일된 오른쪽의 test.js에서는 type이 사라졌음을 볼 수 있다.

 

실제로 js로 컴파일되는 과정에서 타입스크립트의 모든 인터페이스,타입,타입 구문은 제거된다.

 

이러한 이유로 타입스크립트에서는 런타임에서의 타입과 선언된 타입이 맞지 않을 수 있다.

 

다음은 이펙티브 타입스크립트에 나오는 예시이다.

 

function setLightSwitch(value:boolean){
	switch(value){
    	case true : 
        	turnLightOn();
            break;
        case false : 
        	turnLightOff();
            break;
        default : 
        	console.log('value가 boolean이 아닌 경우가 있을까요')
        }
}

위 함수에서 default가 실행될 상황이 있을까??

 

바로 api호출에서 가능하다.

interface LightApiRes {
	lightSwitchValue : boolean;
}

async function setLight(){
	const res = await fetch('/light');
	const result : LightApiRes = await res.json();
	setLightSwitch(result.lightSwitchValue);
}

'/light' 를 요청하면 그 결과로 LightApiRes를 반환하라고 선언했지만, 실제로 그렇게 되리란 보장은 없다.

 

API를 잘못 파악했다거나, 배포후 API가 바뀌어서 lightSwitchValue가 boolean이 아닌 문자열이 되어도 런타임에는 타입체크를 하지 않기 때문에 lightSwitchValue의 타입이 boolean임이 보장되지 않는다.

 

이때 런타임에서도 타입을 보장하기 위해서는 이펙티브 타입스크립트에서는 typeof, in 사용등을 권하고 있다.

 

예를들면 다음과 같다.

async function setLight() {
  const res = await fetch("/light");
  const result: LightApiRes = await res.json();
  typeof result.lightSwitchValue === "boolean" && // 런타임에서도 사라지지 않는 타입체크
    setLightSwitch(result.lightSwitchValue);
}

 

 

회사에서 프로젝트를 하면서 스웨거나 코드젠을 통해 서버에서 오는 response의 타입을 프론트에서 전달받았는데, 그렇게 하는 이유를 이제서야 알 것 같다. 서버에서의 내려주는 response 타입과 프론트에서 사용하는 response의 타입을 일치시키는 장치였던 것이다.
(그럴일은 없겠지만 만약 백엔드에서 맘대로 response 타입을 바꿔서 재배포하면 스웨거고 코드젠이고 소용없을 것 같긴하다.)

 

이유를 모르고 그냥 '편리하니까' 사용했던 장치들의 필요성을 알게되면서 퍼즐이 맞춰지는 느낌이 든다.

 

반응형