TypeScript 5.x 시리즈의 주요 변경사항을 버전별로 정리하고, 타입 시스템의 진화 방향과 개발자 경험 개선을 조망합니다.
TypeScript는 2012년 첫 등장 이후 JavaScript 생태계에서 사실상의 표준 타입 시스템으로 자리 잡았습니다. 특히 5.x 시리즈(2023년 3월~2025년)는 TC39 표준 데코레이터, const 타입 파라미터, 명시적 리소스 관리 등 패러다임 수준의 변화를 가져왔습니다. 이 장에서는 5.0부터 5.8까지의 핵심 변경사항을 조망하고, 이 시리즈에서 깊이 다룰 주제들의 전체 지도를 그려봅니다.
TypeScript 4.x 시리즈가 타입 시스템의 표현력을 확장하는 데 집중했다면, 5.x 시리즈는 크게 세 가지 방향으로 진화했습니다.
using 선언, import 속성 등 JavaScript 표준을 선제적으로 지원const 타입 파라미터, NoInfer, 추론된 타입 가드 등으로 개발자가 명시적 타입을 덜 쓰면서도 정확한 타입을 얻을 수 있게 개선5.0은 이 시리즈에서 가장 많은 지면을 할애할 버전입니다. 두 가지 핵심 기능이 도입되었습니다.
TC39 표준 데코레이터: TypeScript의 실험적 데코레이터(experimentalDecorators)와 별개로, TC39 Stage 3 데코레이터 표준을 네이티브로 지원하기 시작했습니다. 클래스, 메서드, 접근자, 필드, getter/setter에 적용할 수 있으며, 런타임 JavaScript와 완전히 호환됩니다.
function log(target: any, context: ClassMethodDecoratorContext) {
const methodName = String(context.name);
function replacement(this: any, ...args: any[]) {
console.log(`Calling ${methodName} with`, args);
return target.call(this, ...args);
}
return replacement;
}
class Calculator {
@log
add(a: number, b: number) {
return a + b;
}
}const 타입 파라미터: 제네릭 함수에서 const 수정자를 사용하면, 인수를 as const로 선언한 것과 동일한 좁은 타입 추론을 얻을 수 있습니다.
function routes<const T extends readonly { path: string; method: string }[]>(
definitions: T
) {
return definitions;
}
// T는 readonly [{ path: "/api/users"; method: "GET" }, ...] 로 추론
const apiRoutes = routes([
{ path: "/api/users", method: "GET" },
{ path: "/api/posts", method: "POST" },
]);그 외에도 --moduleResolution bundler 옵션, export type * 지원, @satisfies/@overload JSDoc 태그 등이 추가되었습니다.
5.1은 비교적 작은 릴리즈였지만, 실무에서 자주 만나는 불편함을 해소했습니다.
undefined를 반환하는 함수의 암시적 반환 허용: 반환 타입이 undefined인 함수에서 return 문 없이도 동작하게 되었습니다.
// 5.1 이전: 에러 — return 문 필요
// 5.1 이후: 정상 동작
function logMessage(msg: string): undefined {
console.log(msg);
// return 문 불필요
}getter/setter 간 서로 다른 타입 허용: getter의 반환 타입과 setter의 매개변수 타입이 달라도 되게 변경되었습니다.
class Resource {
#data: string | null = null;
get value(): string {
if (!this.#data) throw new Error("Not loaded");
return this.#data;
}
set value(input: string | null) {
this.#data = input;
}
}5.2의 핵심은 명시적 리소스 관리(Explicit Resource Management) 지원입니다. TC39 Stage 3 제안인 using 선언을 통해, 파일 핸들이나 데이터베이스 연결 같은 리소스를 스코프 종료 시 자동으로 정리할 수 있습니다.
function processFile() {
using file = openFile("data.txt");
// file을 사용한 작업...
// 스코프가 끝나면 file[Symbol.dispose]()가 자동 호출
}
async function queryDatabase() {
await using connection = await connectToDb();
// connection을 사용한 작업...
// 스코프가 끝나면 connection[Symbol.asyncDispose]()가 자동 호출
}또한 데코레이터 메타데이터 API가 추가되어, 데코레이터가 클래스에 메타데이터를 부착하고 이를 런타임에 읽을 수 있게 되었습니다.
Import Attributes 지원이 핵심입니다. import 문에 속성을 추가하여 모듈 로더에 힌트를 줄 수 있습니다.
import config from "./config.json" with { type: "json" };
import styles from "./styles.css" with { type: "css" };switch(true) 패턴에서의 타입 좁히기가 개선되었고, resolution-mode를 import 타입에서도 사용할 수 있게 되었습니다.
5.4는 타입 추론을 세밀하게 제어하는 도구를 가져왔습니다.
NoInfer 유틸리티 타입: 특정 위치에서 타입 추론이 일어나지 않도록 막습니다. 라이브러리 설계에서 의도하지 않은 타입 확장을 방지하는 핵심 도구입니다.
function createSignal<T>(initialValue: T, options?: { fallback: NoInfer<T> }) {
// ...
}
// T는 "hello"가 아닌 string으로 추론되지 않음
createSignal("hello", { fallback: "world" }); // OK
createSignal("hello", { fallback: 42 }); // Error!또한 클로저 내 좁혀진 타입 보존이 개선되어, if 블록 안에서 좁혀진 타입이 콜백 함수 내에서도 유지됩니다.
function processValue(value: string | number) {
if (typeof value === "string") {
// 5.4 이전: 클로저 안에서 value가 string | number로 확장될 수 있었음
// 5.4 이후: string으로 유지
setTimeout(() => {
console.log(value.toUpperCase()); // OK
}, 100);
}
}추론된 타입 가드(Inferred Type Predicates): 함수가 타입 가드 역할을 하는지 TypeScript가 자동으로 판단합니다.
// 5.5 이전: 반환 타입에 is 가드를 명시해야 했음
// 5.5 이후: 자동 추론
function isString(value: unknown) {
return typeof value === "string";
}
const values: (string | number)[] = ["a", 1, "b", 2];
const strings = values.filter(isString);
// strings: string[] (5.5 이전에는 (string | number)[] 였음)정규식 구문 검사: TypeScript가 정규식 리터럴의 구문 오류를 컴파일 타임에 잡아냅니다.
// 5.5에서 에러 감지
const regex = /(?<=a{2,1})/; // Error: 수량자 범위 오류Isolated Declarations 모드도 도입되어, 선언 파일(.d.ts) 생성이 타입 검사 없이 가능해졌습니다. 이는 대규모 모노레포에서 빌드 병렬화를 가능하게 합니다.
항상 truthy한 값에 대한 Nullish 검사 경고: 실수로 잘못된 조건을 작성하는 것을 방지합니다.
// 5.6에서 경고
if (/regex/) {
// 정규식 리터럴은 항상 truthy — 아마 .test()를 쓰려 했을 것
}Iterator Helper 메서드: IteratorObject 타입이 추가되어, map, filter, take 등의 이터레이터 헬퍼를 타입 안전하게 사용할 수 있습니다.
상대 경로에 대한 경로 다시쓰기(Path Rewriting): --rewriteRelativeImportExtensions 옵션으로 .ts 확장자를 .js로 자동 변환합니다.
// 소스 코드에서
import { helper } from "./utils.ts";
// 출력에서 자동 변환
import { helper } from "./utils.js";--target es2024가 추가되었고, Symbol.dispose 관련 내장 타입이 개선되었습니다.
--erasableSyntaxOnly 옵션: Node.js의 --experimental-strip-types와 호환되도록, 타입 전용 구문만 사용하도록 강제합니다. enum, namespace, 파라미터 프로퍼티 등 런타임에 영향을 주는 TypeScript 전용 구문을 사용하면 에러가 발생합니다.
// --erasableSyntaxOnly 모드에서 에러
enum Direction { Up, Down } // Error: enum은 erasable하지 않음
// 대안: const 객체 + as const
const Direction = {
Up: 0,
Down: 1,
} as const;--module nodenext에서의 require() ESM 지원과 반환 타입 좁히기 개선도 포함되었습니다.
| 방향 | 주요 기능 | 관련 버전 |
|---|---|---|
| ECMAScript 정렬 | 데코레이터, using, Import Attributes | 5.0, 5.2, 5.3 |
| 타입 추론 강화 | const 타입 파라미터, NoInfer, 추론된 타입 가드 | 5.0, 5.4, 5.5 |
| 안전성 향상 | 정규식 검사, truthy/nullish 경고, 클로저 좁히기 | 5.4, 5.5, 5.6 |
| 빌드 인프라 | Isolated Declarations, 경로 다시쓰기, erasableSyntaxOnly | 5.5, 5.7, 5.8 |
이 시리즈는 TypeScript 5.x의 핵심 기능을 단순히 나열하는 것이 아니라, 각 기능의 원리, 설계 의도, 실전 활용 패턴을 깊이 있게 다룹니다.
const 타입 파라미터와 satisfies 연산자 — 타입 추론을 정밀하게 제어하는 두 가지 핵심 도구using 선언과 명시적 리소스 관리 — C#의 using, Python의 with에 대응하는 JavaScript/TypeScript의 리소스 관리infer 키워드NoInfer와 새로운 유틸리티 타입 — 라이브러리 설계를 위한 타입 추론 제어tsconfig.json 최적화, 프로젝트 참조, Isolated Declarations이 시리즈를 효과적으로 학습하려면 다음 환경을 갖추는 것을 권장합니다.
# Node.js 20+ 및 TypeScript 5.8 설치
node --version # v20.0.0+
npm install -g typescript@latest
tsc --version # Version 5.8.x
# 또는 프로젝트 로컬 설치
npm init -y
npm install typescript@latest --save-dev
npx tsc --initTypeScript Playground(typescriptlang.org/play)에서 버전을 전환하며 코드를 실험할 수 있습니다. 각 장의 예제를 직접 실행해보면 학습 효과가 크게 높아집니다.
TypeScript 5.x는 단순한 버전 업데이트가 아닌, JavaScript 표준과의 정렬, 타입 추론의 정교화, 대규모 프로젝트 지원이라는 세 축으로 진화해왔습니다. 다음 장부터는 각 기능의 원리와 활용법을 하나씩 깊이 파고들어 보겠습니다. 먼저 2장에서는 타입 추론을 정밀하게 제어하는 const 타입 파라미터와 satisfies 연산자를 살펴봅니다.
이 글이 도움이 되셨나요?
관련 주제 더 보기
TypeScript의 타입 추론을 정밀하게 제어하는 두 가지 핵심 도구인 const 타입 파라미터와 satisfies 연산자의 원리, 차이점, 실전 활용 패턴을 다룹니다.
TypeScript 5.0에서 도입된 TC39 Stage 3 데코레이터의 원리, API 구조, 실전 패턴을 다루고, 기존 실험적 데코레이터와의 차이를 분석합니다.
TypeScript 5.2에서 도입된 using 선언과 Symbol.dispose를 활용한 명시적 리소스 관리 패턴을 실전 예제와 함께 심층 분석합니다.