본문으로 건너뛰기

안동민 개발노트

본문 시작

타입스크립트의 역사와 필요성

대규모 JavaScript에서 동적 타입이 만드는 오류와 협업 비용을 살펴보고 TypeScript가 등장한 이유를 이해합니다.

타입스크립트를 처음 배우려 할 때 가장 많이 듣는 말은 자바스크립트 잘하면 굳이 필요 없다는 이야기입니다.

짧은 예제 수준에서는 그 말이 맞아 보일 수 있지만, 코드가 커지고 팀이 커질수록 상황이 달라집니다.

함수 하나의 인자 타입이 잘못 전달된 문제도 런타임에서 늦게 터지면 원인 추적에 많은 시간을 쓰게 됩니다.

초보 단계에서는 문법보다 이런 늦게 드러나는 오류가 더 무섭게 느껴지는 경우가 많습니다.

타입스크립트는 그 문제를 해결하려고 등장한 도구입니다.

이 절에서는 타입스크립트의 역사만 소개하는 데서 멈추지 않고, 왜 지금도 많은 팀이 타입스크립트를 표준으로 채택하는지 실무적 이유까지 함께 짚어보겠습니다.

TypeScript는 늦게 터질 오류를 작성 단계로 당긴다

자바스크립트의 유연성은 빠른 시작을 돕지만 규모가 커질수록 값의 형태를 놓치기 쉽습니다.

  1. 1
    문제

    값의 형태가 실행 중에야 드러나 디버깅 비용이 커집니다.

  2. 2
    해결

    함수 인자와 데이터 구조의 의도를 타입으로 먼저 표시합니다.

  3. 3
    효과

    오류 발견, 리팩터링, 협업 기준이 코드 작성 단계로 이동합니다.


자바스크립트의 비약적인 성장과 그림자

타입스크립트를 이해하려면 먼저 자바스크립트(JavaScript)를 짚고 넘어가야 합니다.

자바스크립트는 웹 브라우저에서 동작하는 유일한 프로그래밍 언어로 시작했지만, 웹의 발전과 함께 빠르게 성장했습니다.

이제는 단순한 웹페이지 동작을 넘어 Node.js 서버, React Native 모바일 앱, Electron 데스크톱 앱까지 개발할 수 있는 전천후 언어로 자리 잡았습니다.

하지만 자바스크립트의 자유분방함은 때때로 개발자에게 큰 고민거리이기도 했습니다.

자바스크립트는 동적 타입(Dynamic Typing) 언어이기 때문에 변수에 어떤 타입이든 할당할 수 있고, 타입이 실행 중에 결정됩니다.

이 유연성은 빠른 개발에 유리하지만, 규모가 큰 프로젝트에서는 예상치 못한 타입 관련 오류를 자주 만들어냅니다.

예를 들어, 다음과 같은 간단한 자바스크립트 코드가 있다고 가정해봅시다.

function add(a, b) {
  return a + b;
}

let result = add(10, 20); // 30
let anotherResult = add("Hello, ", "TypeScript"); // "Hello, TypeScript"
let problematicResult = add(10, "20"); // "1020" (의도치 않은 문자열 연결)

add 함수는 숫자 덧셈을 의도했지만 문자열을 인자로 전달해도 오류 없이 실행됩니다.

숫자와 문자열을 함께 전달하면 의도와 전혀 다른 결과가 나올 수도 있습니다.

이런 문제는 코드 규모가 커지고 협업자가 많아질수록 치명적인 버그로 이어지기 쉽습니다.

개발자는 실행 전까지 타입 오류를 발견하기 어렵고, 결국 디버깅에 많은 시간을 쓰게 됩니다.

JavaScript는 빠르지만 의도와 값이 어긋날 수 있다

같은 함수가 숫자 덧셈과 문자열 연결을 모두 허용하면 작은 예제는 편해도 큰 프로젝트에서는 위험해집니다.

  1. 1
    자유로운 값

    변수와 인자에 여러 타입이 들어갈 수 있습니다.

  2. 2
    늦은 발견

    문제는 테스트나 실제 실행 중에 드러나는 경우가 많습니다.

  3. 3
    추적 비용

    호출부가 많을수록 잘못된 값의 출처를 찾기 어려워집니다.


마이크로소프트의 해답, 타입스크립트의 등장

자바스크립트의 이러한 한계를 극복하고자 등장한 것이 바로 타입스크립트입니다.

2012년 마이크로소프트에서 개발을 시작하여 오픈소스로 공개된 타입스크립트는 자바스크립트의 상위 집합(Superset) 언어입니다.

즉, 유효한 모든 자바스크립트 코드는 타입스크립트 코드이기도 합니다.

타입스크립트는 자바스크립트에 타입(Type) 개념을 도입하여, 개발자가 코드 작성 단계에서부터 변수나 함수의 타입을 명시할 수 있도록 합니다.

이를 통해 다음과 같은 장점들을 얻을 수 있습니다.

  • 강력한 타입 체크: 코드를 실행하기 전(컴파일 시점)에 타입 관련 오류를 미리 발견하고 방지할 수 있습니다. 위 add 함수의 예시에서, 타입스크립트를 사용했다면 잘못된 타입의 인자가 전달되었을 때 개발 단계에서 즉시 경고를 받게 됩니다.
  • 코드의 가독성 및 유지보수성 향상: 코드에 명시된 타입 정보는 해당 변수나 함수가 어떤 데이터를 다루는지 명확히 보여줍니다. 이는 다른 개발자가 코드를 이해하고 수정하는 데 큰 도움을 주며, 장기적인 관점에서 프로젝트의 유지보수 비용을 줄여줍니다.
  • 개발 생산성 증대: 타입 정보 덕분에 IDE(통합 개발 환경)의 도움을 받아 코드 자동 완성, 리팩토링, 오류 탐지 등 다양한 기능을 더욱 효과적으로 활용할 수 있습니다. 개발자는 잠재적인 오류에 대한 걱정을 덜고, 본질적인 기능 개발에 집중할 수 있게 됩니다.
  • 대규모 프로젝트에 적합: 타입 시스템은 복잡한 애플리케이션의 구조를 명확하게 정의하고 관리하는 데 필수적입니다. 여러 개발자가 협업하는 대규모 프로젝트에서 타입스크립트는 코드의 일관성과 안정성을 확보하는 데 핵심적인 역할을 합니다.

정리하면 타입스크립트는 자바스크립트 생태계를 유지하면서 정적 타입 검사를 더해, 변경에 강한 코드를 작성하도록 돕는 도구입니다.

다음 절부터는 타입을 읽고 좁히고 설계하는 기본 절차를 차례로 확인합니다.

다만 타입스크립트 도입 자체가 자동으로 품질을 보장해 주지는 않습니다.

any 남용, 부정확한 타입 단언, 느슨한 컴파일 설정을 사용하면 자바스크립트와 큰 차이가 없어집니다.

핵심은 타입을 쓴다가 아니라 타입으로 의도를 명확히 표현한다는 관점을 유지하는 것입니다.

TypeScript는 JavaScript 위에 타입 검사를 얹은 언어다

기존 생태계를 버리지 않고 정적 검사와 도구 지원을 추가하려는 선택에서 출발했습니다.

  1. 상위 집합

    유효한 JavaScript 코드는 대부분 TypeScript 코드로 시작할 수 있습니다.

  2. 정적 검사

    실행 전 컴파일 단계에서 타입 불일치를 먼저 알려줍니다.

  3. 도구 강화

    자동 완성, 탐색, 리팩터링이 타입 정보를 기준으로 정확해집니다.

아래 다이어그램은 타입스크립트를 도입할 때 얻는 효과를 오류 발견 시점, 협업 계약, 리팩터링 안정성으로 나누어 정리한 것입니다.

TypeScript의 효과는 발견 시점과 협업 비용에서 나타난다

타입을 쓰면 오류가 사라지는 것이 아니라 더 이른 단계에서 더 좁은 범위로 드러납니다.

  1. 1
    오류 발견

    컴파일 전에 잘못된 인자와 반환값을 확인합니다.

  2. 2
    협업 계약

    함수와 모듈의 사용법이 타입 선언으로 공유됩니다.

  3. 3
    변경 안정성

    리팩터링 후 영향 범위를 에디터와 빌드가 함께 확인합니다.

학습 체크 포인트

아래 기준을 기준으로 현재 이해 수준을 점검하면 다음 절 진입 시 시행착오를 줄일 수 있습니다.

  • 타입 표기를 '문법 추가'가 아니라 '의도 명세'로 설명할 수 있는지 확인합니다.
  • 컴파일 시점 오류와 런타임 오류를 구분해 실제 사례로 말할 수 있는지 점검합니다.
  • any 사용을 최소화해야 하는 이유를 유지보수 관점으로 정리해 봅니다.

아래 다이어그램은 타입스크립트가 필요한 상황을 늦은 오류, 협업 계약, 리팩터링 안정성 관점으로 다시 묶어 보여줍니다.

규모가 커질수록 TypeScript의 가치가 선명해진다

혼자 쓰는 짧은 스크립트보다 팀과 장기 유지보수 코드에서 타입 계약의 효과가 커집니다.

  1. 01
    늦은 오류

    런타임 장애 전에 타입 불일치를 걸러냅니다.

  2. 02
    공유 모델

    데이터 구조를 코드 안에서 읽을 수 있게 만듭니다.

  3. 03
    안전한 수정

    함수 시그니처 변경이 호출부까지 추적됩니다.

타입 시스템 학습 연결 메모

다음 절에서는 타입 시스템을 실제 코드에 적용합니다.

이번 절에서 정리한 기준을 기반으로, 타입을 붙이는 순서와 범위를 의도적으로 설계하는 연습으로 이어갑니다.

특히 첫 타입 선언 위치를 근거와 함께 설명할 수 있는지까지 확인하면 이후 절의 학습 연결이 훨씬 매끄러워집니다.

아래 다이어그램은 타입스크립트 도입 판단을 오류 비용, 협업 계약, 점진 적용 순서로 다시 점검합니다.

TypeScript 도입은 오류 비용과 팀 규모를 기준으로 판단한다

모든 프로젝트에 무조건 필요한 것은 아니지만, 변경 비용이 커지는 순간부터 효과가 빠르게 커집니다.

  1. 01
    오류 비용

    장애나 디버깅 비용이 크면 타입 검사의 가치가 올라갑니다.

  2. 02
    협업 경계

    API, 상태, 데이터 모델처럼 약속이 필요한 곳부터 적용합니다.

  3. 03
    점진 적용

    설정과 타입 강도를 단계적으로 높여 학습 부담을 낮춥니다.

이 다이어그램은 타입스크립트의 역사와 필요성 학습을 선언 위치, 타입 좁히기, 재사용 경계 순서로 마무리합니다.

첫 장의 목표는 타입을 붙일 위치를 판단하는 것이다

문법 이름을 외우기 전에 어떤 값이 경계가 되고 어떤 오류를 막는지 보는 연습이 먼저입니다.

  1. 01
    선언 위치

    함수 인자, 반환값, 외부 데이터처럼 계약이 필요한 곳을 찾습니다.

  2. 02
    타입 좁히기

    조건문과 검사로 값의 가능성을 안전하게 줄입니다.

  3. 03
    재사용 경계

    반복되는 구조는 타입 별칭과 인터페이스로 묶습니다.

아래 다이어그램은 TypeScript가 필요한 이유를 오류 시점, 협업, 유지보수 관점으로 다시 압축합니다.

TypeScript가 필요한 이유는 빠른 피드백과 명확한 계약이다

핵심은 JavaScript를 버리는 것이 아니라 작성 중에 더 많은 정보를 얻는 것입니다.

  1. 01
    오류 시점

    실행 후가 아니라 작성·컴파일 단계에서 문제를 봅니다.

  2. 02
    협업

    함수와 데이터의 의도를 타입으로 공유합니다.

  3. 03
    유지보수

    변경 영향이 타입 검사와 도구 지원으로 드러납니다.