밤 11시, 배포한 지 10분 만에 알림이 울린다. "결제 페이지에서 에러가 나요." 로그를 열어 보니 원인은 허무하다. 서버가 내려준 값이 문자열 "0"이었는데, 코드에서는 숫자 0으로 여기고 price - discount를 계산한 것이다. 자바스크립트는 이 실수를 조용히 넘어간다. 실행되기 전까지 아무도 몰랐고, 하필 그걸 사용자가 먼저 발견했다.

이런 경험이 쌓이면 자연스럽게 드는 생각이 있다. "실행하기 전에, 이 값이 숫자인지 문자열인지 누가 미리 좀 알려주면 안 되나?" 타입스크립트(TypeScript)는 정확히 그 질문에 대한 답이다.

타입스크립트는 새로운 언어가 아니다

타입스크립트를 처음 들으면 "또 새 언어를 배워야 하나" 싶어 부담스럽다. 하지만 타입스크립트는 자바스크립트에 '타입'이라는 안전장치를 덧붙인 것에 가깝다. 문법의 90%는 우리가 이미 아는 자바스크립트 그대로다. 실제로 잘 짠 자바스크립트 코드는 확장자만 .ts로 바꿔도 대부분 그냥 동작한다.

핵심 차이는 딱 하나다. 값에 "이건 숫자야", "이건 문자열이야"라고 미리 이름표를 붙일 수 있다는 것. 그러면 편집기가 코드를 실행하기도 전에 잘못된 조합을 빨간 줄로 알려준다.

let price: number = 1000;
let coupon: string = "0";

// 아래 줄에서 편집기가 곧바로 경고한다
// '문자열은 number에 넣을 수 없습니다'
price = coupon; // 실행 전에 잡힌다

브라우저는 타입스크립트를 직접 이해하지 못한다. 그래서 마지막에는 타입 정보를 걷어낸 순수 자바스크립트로 컴파일(변환)된다. 즉 타입은 개발하는 동안만 우리를 지켜주는 감독관이고, 실제 실행되는 코드는 여전히 익숙한 자바스크립트다.

가장 자주 쓰는 기본 타입들

처음엔 세 가지만 알아도 충분하다. number, string, boolean. 여기에 여러 값을 담는 배열과 짝을 이룬 데이터를 표현하는 객체 타입이 더해진다.

let age: number = 32;
let name: string = "지훈";
let isActive: boolean = true;

// 문자열들의 배열
let tags: string[] = ["php", "mysql", "linux"];

// 객체의 모양을 미리 정의
interface User {
  id: number;
  name: string;
  email?: string; // ? 는 '있어도 되고 없어도 됨'
}

const user: User = { id: 1, name: "지훈" };

여기서 interface가 특히 강력하다. 객체가 어떤 모양이어야 하는지 설계도를 그려 두는 것이다. 이후 user.까지만 쳐도 편집기가 id, name, email을 자동으로 추천해 준다. 오타로 user.emial이라고 쓰면 그 자리에서 바로 잡힌다. 기억력에 의존하던 일을 도구가 대신 해 준다.

함수에 타입을 붙이면 달라지는 것

타입의 진가는 함수에서 드러난다. 어떤 값을 받아서 어떤 값을 돌려주는지 계약을 명시하기 때문이다.

function totalPrice(price: number, quantity: number): number {
  return price * quantity;
}

totalPrice(1000, 3);      // 3000
totalPrice(1000, "3");    // "3"은 number가 아니다 → 에러

맨 앞의 결제 사고를 떠올려 보자. 만약 totalPrice의 매개변수에 number라고 못을 박아 두었다면, 문자열 "0"을 넘기려는 순간 편집기가 빨간 줄을 그었을 것이다. 밤 11시의 알림이 오후 3시의 빨간 줄로 앞당겨지는 것, 이것이 타입스크립트가 파는 가장 큰 가치다.

버그를 고치는 가장 저렴한 순간은, 아직 버그가 되기 전이다.

그래도 부담스럽다면, 이렇게 시작하자

타입스크립트를 처음부터 완벽하게 쓰려고 하면 오히려 지친다. 모든 값에 타입을 다 붙이지 않아도 된다. 사실 타입스크립트는 타입을 스스로 추론하는 능력이 뛰어나서, let count = 0이라고만 써도 알아서 number로 이해한다.

현실적인 시작 순서를 제안하자면 이렇다. 첫째, 기존 프로젝트라면 새로 만드는 파일부터 .ts로 써 본다. 둘째, 함수의 매개변수와 반환값에만 타입을 붙인다. 이것만으로도 버그의 상당수가 걸러진다. 셋째, 자주 쓰는 데이터 모양은 interface로 정리한다. 넷째, 도저히 타입을 정하기 어려운 값은 임시로 any를 쓰되, 나중에 하나씩 구체적인 타입으로 바꿔 간다.

any는 "타입 검사를 잠깐 꺼 두겠다"는 뜻이라 남용하면 타입스크립트를 쓰는 의미가 없어진다. 하지만 처음 옮겨 오는 단계에서 막힐 때 숨통을 틔워 주는 비상구로는 쓸 만하다.

작은 프로젝트에도 값어치가 있을까

혼자 만드는 짧은 스크립트라면 타입 없이도 충분하다. 하지만 코드가 몇백 줄을 넘고, 몇 주 뒤의 내가 다시 열어 보게 되고, 다른 사람과 함께 고치는 순간부터 이야기가 달라진다. 그때 타입은 살아 있는 문서 역할을 한다. 이 함수가 뭘 받고 뭘 돌려주는지, 주석을 뒤지지 않아도 코드 자체가 말해 준다.

정리하면 타입스크립트는 자바스크립트를 대체하는 게 아니라, 자바스크립트가 조용히 넘겨 버리던 실수를 실행 전에 붙잡아 주는 보조 장치다. 배우는 비용은 생각보다 작고, 돌려받는 것은 밤늦은 알림이 줄어드는 평온함이다. 오늘 만드는 파일 하나를 .ts로 바꾸고, 함수 하나에 타입을 붙여 보는 것. 딱 그만큼의 작은 시도로 시작해 보길 권한다.