🗄️ TypeORM0. TypeORM의 기초📖 개요

00-foundations

이 챕터가 답하는 질문: TypeORM은 도대체 무엇이고, 다른 ORM(Prisma·Drizzle·Sequelize…)과 어떻게 다르며, 왜 데코레이터에 모든 것을 걸었는가? 한 줄 답 (Pyramid Top): “TypeORM은 데코레이터로 클래스에 메타데이터를 박아 컴파일 타임 타입런타임 메타를 동시에 얻는 DataMapper ORM이다 — 그 한 줄 트릭이 매력과 한계의 출발점이다.”


한 문장 답 (Pyramid Top)

‘TypeORM’이라는 단어는 세 개의 다른 것을 동시에 가리킨다 — ① 데코레이터로 메타데이터를 박는 패러다임, ② 그 메타를 SQL로 번역하는 런타임, ③ Repository와 DataMapper 패턴이 박힌 API 표면. 이 챕터는 셋을 분리해서 이름을 붙이고, 다른 ORM과 어디가 다른지, 왜 2016년에 태어났는지를 한 층씩 벗긴다.


챕터 지도 (Mermaid)


Why — 왜 이 챕터부터 시작하나

“TypeORM은 TypeScript용 ORM이다”라는 한 줄 정의가 거의 모든 오해의 출발점이다. 이 정의는 세 가지를 동시에 흐린다 — TypeScript 전용이 아니라 데코레이터 + reflect-metadata에 묶여 있고, ORM이라는 한 카테고리 안에서도 ActiveRecord와 DataMapper가 갈리며, Prisma·Drizzle 같은 후발주자가 같은 자리에 있는 것이 아니라 다른 트레이드오프를 산다.

상위 챕터에서 만나게 될 거의 모든 헷갈림이 여기서 출발한다.

  • “왜 @Entity 한 줄로 테이블이 만들어지지?” → 01-what-is-typeorm.mdx
  • “왜 TypeORM 0.3.x로 올리면서 코드가 다 깨졌나?” → 02-history-and-ecosystem.mdx
  • “Prisma로 갈아탈까 말까?” → 03-typeorm-vs-other-orms.mdx
  • “데코레이터 한 줄로 뭐가 어떻게 박히는 거지?” → 04-decorator-and-metadata.mdx
  • “결국 TypeORM을 어떻게 머릿속에 그려야 하나?” → 05-mental-model.mdx

이 챕터는 ‘TypeORM’이라는 단어 안에 숨어 있는 5개의 분리된 개념에 각각 이름을 붙인다. 이름을 붙이고 나면, 위 질문들이 자동으로 풀린다.


How — 어떻게 읽나

다음 5개 문서를 순서대로 읽으면 한 시간 정도 걸린다. 각 문서는 독립적으로도 읽히지만, 순서가 누적적이다.

#파일읽는 데핵심 키워드
0101-what-is-typeorm.mdx12분decorator, reflect-metadata, DataMapper, ActiveRecord, EntityManager
0202-history-and-ecosystem.mdx12분2016, NestJS, 0.2.x → 0.3.x, TC39 Stage, lerna monorepo
0303-typeorm-vs-other-orms.mdx14분Prisma, Drizzle, MikroORM, Sequelize, Kysely, 데코레이터 vs 스키마 vs SQL
0404-decorator-and-metadata.mdx14분experimentalDecorators, emitDecoratorMetadata, reflect-metadata, design:type
0505-mental-model.mdx10분컴파일 타임 vs 런타임 이중 신원, MetadataArgsStorage, single source of truth

의존성: 02는 01을, 03은 0102를, 04는 01을, 05는 14 모두를 통합한다.


What — 한 페이지 요약 (모든 문서의 핵심 한 줄)

문서한 줄 결론
01TypeORM은 데코레이터 + reflect-metadata에 기댄 DataMapper ORM이고, ActiveRecord 모드는 권장하지 않는 호환 옵션에 가깝다.
02TypeORM은 2016년 Umed Khudoiberdiev가 시작했고, NestJS가 기본 ORM으로 채택하며 사실상 표준이 됐다 — 그러나 0.3.x 전환이 조용한 분기점이었다.
03Prisma는 스키마 우선, Drizzle은 SQL 우선, MikroORM은 Unit of Work 우선, TypeORM은 클래스 우선. 같은 자리에 있는 게 아니라 다른 트레이드오프를 산다.
04@Column은 마법이 아니다 — Reflect.metadata클래스 prototype에 메타 객체를 박는 평범한 함수이고, TS가 emitDecoratorMetadata타입까지 넣어준다.
05TypeORM의 핵심 멘탈모델은 “클래스 = 테이블 = 메타데이터 묶음” — 한 클래스가 컴파일 타임 타입과 런타임 메타라는 이중 신원을 동시에 가진다.

What-if — 이 챕터를 건너뛰면

  • 데코레이터를 마법으로 보면: experimentalDecorators를 끄거나 SWC/esbuild로 옮길 때 모든 엔티티가 조용히 망가지는데 원인을 모른다.
  • DataMapper와 ActiveRecord를 같은 것으로 보면: BaseEntity를 상속해 user.save()로 짜다가 도메인 객체가 영속성을 알아버리는 누수가 생긴다.
  • 다른 ORM과 비교 없이 TypeORM부터 배우면: 모든 한계가 데코레이터 패러다임의 본질적 비용임을 모르고 *“TypeORM 버그”*라고 부르게 된다.
  • 0.2.x와 0.3.x를 구분 못 하면: 인터넷 글의 절반은 deprecated된 사용법이라 그대로 따라 하면 findOne(id)부터 깨진다.

Insight — 한 단락 이야기

“TypeORM은 데코레이터 spec이 살아 있을 때 태어난 ORM이다”

2016년, TypeScript는 막 1.8을 지나 2.0으로 가는 길목이었고, TC39 데코레이터 제안서는 Stage 1이었다. Angular 2가 데코레이터로 메타프로그래밍을 정착시키고 있었고, Umed Khudoiberdiev라는 한 개발자가 Hibernate를 TypeScript로 가져오자는 발상을 깃허브에 올렸다. 같은 해 NestJS가 Angular 스타일 백엔드 프레임워크로 등장하며 TypeORM을 기본 ORM으로 채택한다. 두 프로젝트는 같은 한 줄에 운명을 걸었다 — “TypeScript는 데코레이터로 의존성을 표현한다.” 9년이 지난 지금, 데코레이터 제안서는 여전히 Stage 3 어딘가를 떠돌고 있고 — TypeORM의 매력과 한계 모두 그 한 줄에 묶여 있다. 이 챕터가 하는 일은 그 한 줄을 다섯 층으로 분해해 이름을 붙이는 것.


한 단락 요약

TypeORM은 데코레이터 + reflect-metadata(01) 위에 역사와 NestJS 결혼(02), 다른 ORM과의 위치 차이(03), 메타데이터가 박히는 메커니즘(04), 클래스 = 테이블 멘탈모델(05)이 차례로 쌓인 구조다. 이 챕터를 끝내면 “TypeORM이 뭐냐”라는 질문 대신 *“내 팀의 코드가 데코레이터 패러다임의 비용을 감당할 만한가, 아니면 스키마/SQL 우선 도구가 더 맞는가”*라는 질문을 던지게 된다. 다음 챕터(01-entity-decorators)는 이 패러다임으로 클래스 한 개를 실제로 테이블로 만드는 일을 다룬다.