반응형

TypeScript는 스크립트 언어일까? 헷갈리는 기초 개념 4가지 정리

💡 이 글에서 다루는 내용

  • TypeScript는 정말 스크립트 언어인가?
  • TypeScript와 Node.js는 어떻게 다른가?
  • JavaScript는 런타임 없이 실행되는 게 맞을까?
  • 결국 JS로 변환되는데 왜 TypeScript를 쓰는가?

안녕하세요. TypeScript로 백엔드를 시작하기 전에, 의외로 많은 개발자들이 흐릿하게 알고 있는 기초 개념부터 정리하고 가려고 합니다.

저도 처음 TypeScript를 접했을 때 "이게 스크립트 언어야? 컴파일 언어야?", "Node.js랑 뭐가 다르지?" 같은 질문에 명확히 답하기 어려웠습니다. 그런데 이 부분을 명확하게 잡고 가야 이후에 어떤 런타임을 쓸지, 어떤 빌드 도구를 쓸지 같은 결정이 훨씬 쉬워집니다.

오늘은 자주 헷갈리는 4가지 질문에 차근차근 답해보겠습니다.


📌 목차

  1. TypeScript는 스크립트 언어인가?
  2. TypeScript와 Node.js는 무엇이 다른가?
  3. JavaScript는 런타임 없이 실행되는가?
  4. 결국 JS로 변환될 텐데 왜 TypeScript를 쓰는가?

1. TypeScript는 스크립트 언어인가?

결론부터 말하면 "엄밀히는 아니지만, 실용적으로는 그렇게 분류해도 큰 문제는 없다" 입니다.

스크립트 언어의 일반적인 정의

학술적으로 명확한 정의는 없지만 보통 이런 특징들을 묶어서 부릅니다.

  • 인터프리터 방식으로 실행 (별도 컴파일 단계 없이 바로 실행)
  • 동적 타입 (런타임에 타입 결정)
  • 짧은 자동화, glue code에 자주 쓰임
  • REPL이 흔함

이 기준에서 JavaScript는 전형적인 스크립트 언어입니다.

TypeScript는 두 가지가 다릅니다

① 컴파일이 필수입니다

TypeScript는 그 자체로는 절대 실행되지 않습니다. 반드시 JavaScript로 변환(트랜스파일)되어야 합니다.

.ts 파일 → [tsc / esbuild / swc] → .js 파일 → Node.js / 브라우저

C나 Java처럼 "소스 → 다른 형태 → 실행"이라는 컴파일 언어의 워크플로우를 따릅니다. 결과물이 기계어가 아니라 JavaScript일 뿐입니다.

이런 언어를 트랜스파일 언어(transpiled language) 또는 컴파일-투-JS 언어라고 부릅니다.

② 정적 타입 시스템이 핵심입니다

스크립트 언어의 큰 특징인 동적 타이핑을 TypeScript는 정면으로 거부합니다. 변수, 함수 인자, 반환 타입을 컴파일 시점에 검증합니다.

TypeScript의 존재 이유 자체가 "JavaScript에 정적 타입을 입히는 것"입니다.

그런데 왜 스크립트 언어처럼 다루는가?

  • tsx, ts-node, Bun, Deno 같은 도구가 .ts 파일을 직접 실행하는 것처럼 보이게 만들어줍니다 (내부적으론 메모리에서 컴파일 후 실행)
  • 결국 동작은 JavaScript로 이루어지므로 JS의 동적 특성을 그대로 물려받습니다
  • 짧은 자동화 스크립트, CLI 도구도 자유롭게 작성 가능합니다

정확한 한 줄 정리

TypeScript는 JavaScript로 컴파일되는 정적 타입 언어입니다. JavaScript가 스크립트 언어이므로 TypeScript도 넓은 의미에서 스크립트 언어 계열에 속하지만, 자체적으로는 컴파일 언어의 특성을 가집니다.


2. TypeScript와 Node.js는 무엇이 다른가?

이건 헷갈리는 게 당연한 주제입니다. 한 번에 정리하면 명확해집니다.

핵심 구분

  • TypeScript = 언어
  • Node.js = 런타임 (실행 환경)

비유하자면 이렇습니다.

분류 언어 실행 환경

자동차 운전 규칙/설계도 도로 + 엔진
음식 레시피 주방 + 가스레인지
프로그래밍 TypeScript, JavaScript Node.js, 브라우저, Bun, Deno

레시피만 있다고 음식이 만들어지지 않습니다. 주방이 있어야 실제 요리가 됩니다.

각각 무엇인가?

JavaScript (언어)

  • ECMAScript 표준에 따른 프로그래밍 언어
  • 문법과 표준 함수를 정의

TypeScript (언어)

  • JavaScript에 정적 타입을 추가한 언어
  • 컴파일하면 JavaScript가 됨

Node.js (런타임)

  • JavaScript를 서버/터미널에서 실행할 수 있게 해주는 프로그램
  • Google V8 엔진(Chrome이 쓰는 그 엔진)에 파일 시스템, 네트워크, OS 접근 같은 추가 기능을 더한 것

관계도

[TypeScript 코드]
       │
       │ tsc / esbuild / tsx 가 변환
       ▼
[JavaScript 코드]
       │
       │ 어디서 실행할까?
       ├──────────────┬──────────────┬──────────────┐
       ▼              ▼              ▼              ▼
   [Node.js]     [브라우저]       [Bun]          [Deno]
   (서버,CLI)    (웹페이지)    (대안 런타임)   (대안 런타임)

JavaScript는 여러 런타임에서 실행 가능합니다. Node.js는 그중 하나일 뿐입니다.

같은 코드, 다른 환경

const message: string = "Hello"
console.log(message)

이 코드가 어디서 돌아가는지에 따라 가능한 일이 달라집니다.

실행 환경 가능한 것 불가능한 것

Node.js 파일 읽기/쓰기, HTTP 서버, OS 접근 DOM 조작, window, document
브라우저 DOM, window, fetch, 사용자 클릭 파일 시스템 직접 접근, OS 명령
Bun Node.js와 거의 호환 + 더 빠름 (대부분 호환)
Cloudflare Workers 엣지에서 HTTP 처리 Node 전용 모듈(fs 등)

흔한 오해 정리

❌ "Node.js로 코딩한다" ✅ 정확히는 "JavaScript/TypeScript로 코딩하고 Node.js에서 실행한다"

❌ "TypeScript는 Node.js 위에서만 돌아간다" ✅ JS로 변환된 후 어떤 런타임에서든 실행됩니다

❌ "Node.js는 언어다" ✅ Node.js는 런타임입니다


3. JavaScript는 런타임 없이 실행되는가?

이 질문에는 중요한 오해가 있습니다.

JavaScript도 런타임 없이는 절대 실행되지 않습니다.

자주 하는 착각

"브라우저에서 <script> 태그로 JS를 그냥 쓸 수 있으니까 런타임이 필요 없다"

"node script.js 치면 그냥 돌아가니까 런타임이 필요 없다"

→ 둘 다 이미 런타임 위에서 실행되고 있는 것입니다. 런타임이 안 보일 뿐입니다.

JavaScript 실행에 반드시 필요한 것

JavaScript는 인터프리터 언어라서 소스 코드를 컴퓨터가 직접 이해하지 못합니다. 누군가가 코드를 읽고 해석해서 CPU가 알아들을 수 있는 명령으로 바꿔줘야 합니다.

그 "누군가"가 바로 JavaScript 엔진이고, 엔진을 감싸 실제 환경을 제공하는 것이 런타임입니다.

[JavaScript 소스 코드]
        │
        ▼
┌─────────────────────────────────┐
│ JavaScript 엔진 (V8, JSCore...)  │  ← 코드 파싱/해석/JIT 컴파일
│ + 표준 라이브러리                 │  ← console, Math, JSON 등
│ + 환경별 API (DOM 또는 fs)        │  ← 환경마다 다름
└─────────────────────────────────┘
         = 런타임

엔진 없이는 console.log("hi") 한 줄도 실행 안 됩니다.

"런타임 없이 실행"처럼 보였던 건 무엇이었나?

상황 실제로는

브라우저에서 <script> 사용 브라우저 자체가 런타임 (V8 + DOM API + fetch 등)
터미널에서 node app.js Node.js가 런타임 (V8 + fs, http 등)
개발자 도구 콘솔에서 1+1 브라우저 런타임에서 실행

JavaScript "단독"으로 실행되는 환경은 존재하지 않습니다.

TypeScript는 한 단계 더

JavaScript:
  [JS 코드] ──────────────→ [런타임] ──→ 실행
                            (필수)

TypeScript:
  [TS 코드] ──[컴파일]──→ [JS 코드] ──→ [런타임] ──→ 실행
            (필수)                      (필수)

tsx, ts-node, Bun, Deno 같은 도구는 컴파일 단계를 자동 처리해줘서 마치 TS를 직접 실행하는 것처럼 보일 뿐, 내부적으로는 JS로 변환 후 런타임에서 실행됩니다.

정확한 비교

항목 JavaScript TypeScript

컴파일/변환 단계 불필요 필수
런타임 필수 필수
단독 실행 가능?

진짜 차이는 "런타임이 필요하냐"가 아니라 이렇게 표현해야 정확합니다.

JavaScript는 소스를 런타임에 바로 던질 수 있고, TypeScript는 소스를 먼저 JS로 바꾼 다음 던져야 한다.

진정한 의미의 "런타임 없이 실행되는 언어"는 C, C++, Rust, Go 같은 네이티브 컴파일 언어들입니다. 컴파일 결과물이 OS가 직접 실행할 수 있는 기계어입니다. JS와 TS는 둘 다 이 부류가 아닙니다.


4. 결국 JS로 변환될 텐데, 왜 TypeScript를 쓰는가?

가장 본질적인 질문입니다. 답은 이렇습니다.

실행은 같지만 개발 과정에서의 안전망과 생산성이 완전히 다르기 때문

비유로 시작

같은 도로를 달리는 두 자동차를 생각해보세요.

  • JavaScript: 안전벨트, 차선이탈 경보, 후방 카메라가 없는 차
  • TypeScript: 같은 차에 안전 보조 장치 풀세팅

목적지(실행 결과)는 같습니다. 하지만 운전하는 동안의 사고 확률, 피로도, 자신감이 완전히 다릅니다.

코드 작성 = 운전 과정입니다.

① 버그를 작성 시점에 잡는다

JavaScript 예시

function getDiscount(user) {
  return user.membership.level * 0.1
}

getDiscount({ name: "Alice" })  // 💥 런타임 에러
// TypeError: Cannot read properties of undefined (reading 'level')

코드를 실행해야, 그것도 이 코드 경로를 실제로 거쳐야만 에러가 발견됩니다. 운이 나쁘면 프로덕션에서 사용자가 발견합니다.

TypeScript 예시

type User = { name: string; membership?: { level: number } }

function getDiscount(user: User) {
  return user.membership.level * 0.1
  //     ^^^^^^^^^^^^^^^ 🔴 에디터에서 즉시 빨간 줄
  // Object is possibly 'undefined'.
}

저장도 하기 전에, 빌드도 하기 전에 에디터에서 잡힙니다. 5초 만에 잡은 버그 vs 프로덕션 장애의 차이입니다.

② 자동완성과 IDE 지원

이게 사실 가장 체감되는 차이입니다.

JavaScript

function processOrder(order) {
  order.    // ← 에디터: "뭐가 있는지 나도 몰라요"
}

order에 뭐가 들어있는지 알려면 함수를 호출하는 모든 곳을 직접 추적해야 합니다.

TypeScript

function processOrder(order: Order) {
  order.    // ← 에디터가 자동 표시:
            //   • id: string
            //   • items: OrderItem[]
            //   • totalAmount: number
            //   • customer: Customer
            //   • createdAt: Date
}

오타도 즉시 잡힙니다(order.totalAmout → 빨간 줄). 큰 코드베이스에서 이 차이는 어마어마합니다.

③ 안전한 리팩토링

User 타입의 name 필드를 fullName으로 바꾸고 싶다고 합시다.

JavaScript의 경우

프로젝트 전체에서 .name을 검색 → 어떤 게 User의 name이고 어떤 게 다른 객체의 name인지 일일이 판단 → 빠뜨리면 런타임에서 터짐 → 두려워서 못 바꿈 → 코드가 점점 더러워집니다.

TypeScript의 경우

F2(rename) 한 번이면 끝. 못 바꾼 곳은 컴파일러가 빨간 줄로 다 알려줍니다.

이걸 "두려움 없는 리팩토링(fearless refactoring)" 이라고 부릅니다. 코드베이스가 커질수록 가치가 기하급수적으로 커집니다.

④ 살아있는 문서

function transferMoney(
  fromAccount: Account,
  toAccount: Account,
  amount: Money,
  options?: { skipValidation?: boolean; idempotencyKey?: string }
): Promise<Transaction>

함수 시그니처만 봐도 입력, 출력, 옵션이 명확합니다. JSDoc 주석 없이도 의도가 드러납니다.

6개월 뒤의 나, 또는 새로 합류한 팀원이 이 함수를 이해하는 시간이 확연히 줄어듭니다.

⑤ 팀 협업 시 계약을 강제한다

여러 명이 함께 일할 때 진짜 가치가 드러납니다.

// 백엔드 (Drizzle 스키마)
type User = { id: number; email: string; createdAt: Date }

// 프론트엔드
const user: User = await fetch('/api/users/1').then(r => r.json())
user.createdAt.getTime()  // ✅ Date 메서드 사용 가능

백엔드가 createdAt을 created_at으로 바꾸면 프론트의 컴파일이 깨집니다. 두 서비스 간 계약이 코드로 강제됩니다.

핵심 통찰

타입 검사는 테스트와 비슷한 자동화된 검증 단계입니다.

"코드를 실행하지 않고도 일부 버그를 자동으로 잡아주는 무료 테스트"

JavaScript 워크플로:
  코드 작성 → 실행 → 에러 발견 → 수정
                ↑ 여기서 처음 문제를 안다

TypeScript 워크플로:
  코드 작성 → 타입 검사 → 변환 → 실행
              ↑ 여기서 이미 잡힘

단점도 분명히 있다

공정하게 말하자면 이런 단점이 있습니다.

단점 현실

빌드 단계 추가 tsx, Bun, Deno로 거의 사라짐
타입 작성 시간 익숙해지면 자동완성 덕에 오히려 빨라짐
학습 곡선 기초는 1~2일, 고급은 몇 주
타입 정의 없는 라이브러리 요즘 인기 라이브러리는 거의 다 제공
타입과 런타임 불일치 런타임 검증은 Zod 같은 별도 도구 필요

언제 JavaScript가 더 나은가?

TypeScript가 만능은 아닙니다. 이런 경우엔 JavaScript가 합리적입니다.

  • 20줄짜리 일회성 스크립트
  • 프로토타입/해커톤
  • 튜토리얼, 학습 코드
  • 마이그레이션 비용이 큰 레거시 JS 프로젝트

통계로 보는 현실

이건 단순한 의견이 아닙니다.

  • State of JS 2023: 신규 프로젝트의 78%가 TypeScript 사용
  • npm 패키지의 90% 이상이 TypeScript 타입 정의 제공
  • Google, Microsoft, Airbnb, Slack, Stripe 등이 자체 코드베이스를 JS → TS로 마이그레이션
  • 신규 프레임워크/라이브러리는 거의 다 TypeScript로 작성 (Hono, Drizzle, Pothos, Next.js, NestJS 등)

이렇게 많은 회사가 비용을 들여서 TS로 바꾸는 이유는, 장기적으로 더 싸기 때문입니다.


🎯 마무리

오늘은 TypeScript의 4가지 기초 개념을 정리해봤습니다.

핵심을 다시 한 번 짚어보면 이렇습니다.

TypeScript는 트랜스파일 언어입니다. 스크립트 언어 계열로 분류해도 무리는 아니지만, 자체적으로는 컴파일 언어의 특성을 가집니다.

TypeScript는 언어, Node.js는 런타임입니다. 서로 다른 층위의 개념이고 보완 관계입니다.

JavaScript도 런타임 없이는 실행되지 않습니다. TypeScript는 거기에 컴파일 단계가 추가될 뿐입니다.

TypeScript의 본질은 "런타임에 발견될 버그의 일부를, 코드 작성 시점에 컴파일러가 미리 잡아주는 시스템"입니다.

프로젝트가 한 페이지 이상 되거나, 한 명 이상이 작업하거나, 한 달 이상 유지될 거라면 TypeScript의 이득이 비용을 거의 항상 압도합니다.

이게 사람들이 "결국 JS로 변환될 텐데"라는 사실을 알면서도 TypeScript를 쓰는 이유입니다.

다음 글에서는 이 TypeScript를 기반으로 실제 백엔드를 어떻게 구성할지, 제가 선택한 스택(Hono, Pothos, GraphQL Yoga, Drizzle, BullMQ)을 하나씩 살펴보겠습니다.

긴 글 읽어주셔서 감사합니다. 도움이 되셨다면 공감과 댓글 부탁드립니다 🙏


📚 함께 보면 좋은 글

  • (다음 글) TypeScript 백엔드 스택 정하기 — Hono, Pothos, Drizzle, BullMQ
  • (다음 글) TypeScript 백엔드 프로젝트 구조 — 모노레포가 답인가?
  • (다음 글) TypeScript 백엔드 테스트 코드 작성하기

🏷️ 태그 #TypeScript #JavaScript #NodeJS #백엔드 #프로그래밍언어 #런타임 #트랜스파일러 #개발기초 #TS입문 #웹개발

반응형

'웹 프로그래밍 > JavaScript&TypeScript' 카테고리의 다른 글

window.onload vs $(document).ready() vs $(window).load()  (0) 2018.10.16
JavaScript xml 파싱  (0) 2016.02.05
JavaScript xml 사용  (0) 2016.01.27
JavaScript 함수 선언  (0) 2016.01.04
반응형

🤖 AI가 코딩은 다 하는데, '내 실력'은 제자리라면? (바이브 코딩의 함정)

최근 AI와 대화하며 코딩하는 이른바 **'바이브 코딩(Vibe Coding)'**으로 퀀트 투자 시스템을 만들고 있습니다. 그런데 어느 순간 이런 현타가 오더군요.

"AI가 나보다 더 잘 아는 것 같은데... 그냥 얘한테 다 맡겨도 될까?" "근데 나중에 돈 잃으면, 나 이거 왜 망했는지 설명할 수 있나?"

분명 내가 만든 프로젝트인데, 정작 나는 구조조차 모르는 소외감을 느끼고 계시진 않나요? 주도권을 되찾고 '진짜 내 실력'을 키우는 생존 전략을 정리했습니다.


1️⃣ 개발자는 이제 '유능한 팀장'이 되어야 한다

코딩의 무게중심이 '구현'에서 **'디렉팅'**으로 옮겨갔습니다. 이제 개발자의 실력은 키보드 타건 속도가 아니라 다음 두 가지에서 결정됩니다.

  • 맥락 설계: AI에게 "수익률 높여줘"라고 하는 건 무능한 팀장입니다. "슬리피지와 수수료 0.015%를 고려해서 보수적인 백테스팅 로직을 짜줘"라고 요구사항의 해상도를 높여야 합니다.
  • 코드 검수: AI가 짠 코드가 '돌아가기만 하는 코드'인지 '유지보수가 가능한 자산'인지 가려내는 안목이 곧 당신의 연봉입니다.

2️⃣ '전달자'가 아닌 '설계자'로 살아남는 법

AI 사이에서 메시지만 배달하다 보면 내 머릿속은 '블랙박스'가 됩니다. 주도권을 잡기 위한 3가지 장치를 마련하세요.

  • 의사결정 로그 강제화: AI에게 "왜 이 시점에 매수했는지" 논리적 근거를 기록하게 하세요. 그래야 사고가 났을 때 범인을 찾을 수 있습니다.
  • AI를 스승으로 활용: 코드를 짜게 한 뒤 반드시 물어보세요. "이 로직을 나한테 PT 하듯이 설명해봐. 이해 안 가면 다음 단계 안 넘어갈 거야."
  • 샌드위치 워크플로우: [인간의 가설] → [AI의 구현] → [인간의 검증] 이 사이클을 지키면 주객전도를 막을 수 있습니다.

3️⃣ AI 시대, 우리가 키워야 할 '진짜 체력'

AI가 증폭기라면, 내 본체가 0일 때 결과는 0입니다. 우리가 매일 단련해야 할 리스트입니다.

핵심 역량 실천 가이드
비판적 사고
AI의 답이 '그럴싸한 개소리'인지 걸러낼 도메인 기초 지식 습득
구조화 능력
코딩 전, 종이와 펜으로 시스템 구조도를 직접 그려보기
언어 표현력
내가 모르는 게 무엇인지 정확한 용어로 정의하는 연습
메타 인지
"AI 없이 이 로직을 5분간 설명할 수 있는가?" 스스로 질문하기

 

💡 마치며: 건축가는 벽돌을 직접 쌓지 않는다

벽돌을 직접 쌓지 않는다고 건축가가 아닌 것은 아닙니다. 하지만 벽돌의 강도와 하중의 원리를 모르는 건축가는 무너지는 집을 지을 뿐이죠.

AI라는 역대급으로 똑똑한 신입 사원을 잘 부리는 **'아키텍트'**가 되느냐, 단순히 AI의 명령을 옮기는 **'우체부'**가 되느냐는 결국 한 끗 차이의 학습 의지에 달려 있습니다.


여러분의 프로젝트는 안전한가요? 혹시 AI에게 영혼까지 맡기고 계신 건 아닌지 오늘 한 번 점검해 보세요!

작성자 한마디: 퀀트 시스템 개발기, 앞으로는 'AI가 짠 코드'가 아니라 'AI를 가르치며 배운 통찰'을 기록해 보려 합니다.

반응형
반응형

레이드 구성

NAS 서버 스토리지를 어떻게 설정할 것인지에 대한 정리

 

레이드란
> 물리적인 여러개의 디스크를 묶어 하나의 논리적인 디스크처럼 사용

raid 구성 방식 최소 디스크 장점 단점 용량
raid0 striping 2 전체 디스크를 사용 하나 디스크가 고장나면 전체 오류 디스크 * 용량
raid1 mirroring 2 안정성이 높다 비용이 비싸며 write 성능이 낮음 디스크 / 2
raid5 striping & parity 3 패러티 정보를 사용하여 성능 향상 및 안정성 확보 디스크 고장시 복구 속도 저하
2개 이상의 디스크 고장시 복구 어려움
디스크 - 1
raid6 striping & double parity 4 2개 디스크에 대한 안정성을 제공 비용이 비싸며 계산비용이 많이 듬 디스크 - 2
raid10 striping & mirroring 4 안정성 및 속도 향상 비용 많이 듬 디스크 / 2

 

striping 방식 : 데이터를 나누어 균등 분산 저장

mirroring 방식 : 디스크에 N개로 복제하여 저장

 

시놀로지에서 제공하는 Raid 계산기
https://www.synology.com/ko-kr/support/RAID_calculator

반응형

+ Recent posts