
약 반년전 어디 면접에 가서
면접관 : 타입스크립트는 컴파일에 돌아가나요? 런타임에 돌아가나요?
나 : (오초간 정적) 런.. 타임이요
면접관 : 타입스크립트가 런타임에 돌아간다고 생각하시는 이유는요?
라는 질문을 듣고... 컴파일 런타임이 먼지도 몰랐던 내가 떠올라 가끔 수치스럽지만,,,
앞으로 알아가면 되기에!! 컴파일타임과 런타임에 대해 알아보려고 한다.
참고로 타입스크립트는 컴파일에서 돌아간다 😭


프로그래밍에서 우리가 작성한 코드를 컴퓨터가 이해할 수 있는 언어로 번역하는 과정
우리가 프로그래밍 언어(C, Java, Python 등)로 작성한 코드는 사실 사람이 이해하기 쉬운 언어이지만, 컴퓨터는 0과 1로 이루어진 기계어(Machine Code) 만 이해할 수 있다.
그래서 사람의 말을 컴퓨터의 말로 바꿔주는 '통역사' 역할이 필요한데,
이 과정이 바로 컴파일이고, 이 일을 수행하는 프로그램을 컴파일러(Compiler) 라고 부른다.

컴파일 과정을 마친 프로그램이 사용자의 컴퓨터나 브라우저에서 실제로 실행되고 있는 시간을 말한다.
쉽게 말해, 우리가 작성한 애플리케이션이 움직이는 순간이다.
이 때는 사용자의 입력(클릭, 스크롤)에 반응하고, API 서버에서 데이터를 받아오는 등 실제 동작이 일어난다.
| 구분 | 컴파일 타임 (Compile Time) | 런타임 (Runtime) |
|---|---|---|
| 의미 | 코드를 번역하고 검사하는 시간 | 번역된 코드를 실제로 실행하는 시간 |
| 주인공 | TypeScript | JavaScript |
| 하는 일 | 문법 검사, 타입 체크, JS로 변환 | 코드 실행, 클릭 이벤트 처리, 서버 통신 |
| 에러 발생 | 빨간 줄 (실행하기도 전에 알려줌) | 프로그램 멈춤 (사용자가 쓰다가 터짐) |

우리가 VS Code에서 코드를 작성하고 저장하거나 빌드 명령어를 입력했을 때 일어나는 과정이다.
타입 검사 (Type Checking): tsc(타입스크립트 컴파일러)가 코드에 이상한 점은 없는지 감시한다.
"숫자 넣기로 했는데 왜 문자를 넣었어?"라며 빨간 줄을 긋는 시점이다.
변환 (Transpiling) 검사를 통과하면, 브라우저가 이해할 수 있는 순수 자바스크립트(JS) 파일로 변환(컴파일)한다.
이 과정에서 모든 '타입 정보(Interface, Type Alias, 제네릭 등)'는 깨끗하게 삭제된다.
변환된 자바스크립트 파일이 브라우저에서 실행되는 시점이다.
만약 컴파일 타임(TS)에서 잡지 못한 에러(예: API 응답 값이 예상과 다름)가 있다면, 이때 프로그램이 멈추거나 오동작하는 런타임 에러가 발생한다.
가장 확실한 차이는 "결과물에 타입이 남아있는가?" 이다.
// 타입 정보가 존재함
function add(x: number, y: number): number {
return x + y;
}
const result = add(10, 20);
// 컴파일 후: 타입 정보가 모두 사라짐 ("삭제"됨)
function add(x, y) {
return x + y;
}
var result = add(10, 20);
타입스크립트는 컴파일 타임에 우리의 실수를 미리 막아주는 역할을 하고, 런타임이 시작되기 전에 사라진다.
타입스크립트는 컴파일단계에서만 검증을 해주기때문에
실제로 api와 통신하고, 사용자를 만나는 런타임에서는 안정성을 검증할 수 없다.
그렇기때문에 코드상으로는 문제가 없더라도, 런타임 에러를 만날 수 있다.
// 1. 실제 서버에서 들어온 데이터 (age가 숫자)
const response = {
name: "김코딩",
age: 30
};
// 2. 내가 작성한 타입 (age를 문자열로 착각함)
interface UserType {
name: string;
age: string; // 👈 여기가 문제!
}
// 3. 타입 단언 (Type Assertion)
// 컴파일 타임: TS는 "그래, 네가 string이라니까 믿을게" 하고 넘어감
const user = response as unknown as UserType;
// 4. 런타임 (실제 실행)
// TS: "age는 문자열이니까 split 써도 돼~" (빨간줄 없음)
// JS: "미쳤어? 숫자한테 split을 어떻게 써!" -> ❌ 런타임 에러 발생
console.log(user.age.split(""));
하지만 Zod로 만든 스키마는 자바스크립트 객체로 남아 런타임에서도 작동할 수 있다.
// 1. 데이터 (여전히 문제 있는 상황)
const response = { name: "김코딩", age: 30 };
// 2. safeParse 실행 (에러 안 터짐!)
const result = UserSchema.safeParse(response);
// 3. 결과 확인 (if문으로 분기 처리)
if (!result.success) {
console.log("형식이 안 맞아요:", result.error.message);
// 함수 종료 or 기본값 사용 등 유연한 대처 가능
return;
}
// ✅ 성공했을 때
// 여기 들어오면 result.data는 무조건 안전한 데이터임이 보장됨
// TS도 result.data.age를 string으로 인식함 (자동 추론)
console.log(result.data.age.split(""));
타입스크립트로만 type을 선언하면 interface등 타입은 모두 컴파일 과정에서 사라지지만,
zod가 있는 파일이 컴파일 되면 브라우저가 읽을 수 있는 형태로 자바스크립트(런타임)에 남게 된다.
// 이건 타입 선언이 아니라, '함수 실행' 코드이다.
const UserSchema = z.object({
name: z.string(),
age: z.number(),
});
// 브라우저가 이 줄을 읽고 실행해서 '검증 기계'를 메모리에 만든다.
const UserSchema = z.object({
name: z.string(),
age: z.number(),
});

내 무지에서 시작된 공부였지만 단순히 "TS는 컴파일 언어다"라고 외우는 것보다, "왜 컴파일 타임에 검사하는지, 그리고 런타임에는 어떤 구멍이 생길 수 있는지" 이해하는 과정이 훨씬 중요하다는 생각이 들었다.
앞으로도 단순히 코드를 치는 것을 넘어, 내 코드가 언제, 어떻게, 어디서 실행되는지 끊임없이 고민하는 개발자가 되어야겠다~!