TypeScript 5.0 새로운 기능 완벽 가이드: 실전 활용법과 마이그레이션 전략
마이크로소프트가 공개한 TypeScript 5.0은 단순한 버전 업그레이드가 아닙니다. 데코레이터의 공식 지원, const 타입 파라미터, 그리고 상당한 성능 개선까지 - 실제 개발 경험을 크게 바꿀 변화들이 포함되어 있습니다. 이 글에서는 주요 기능과 실제 적용 사례, 마이그레이션 시 고려할 점들을 상세히 다룹니다.
1. Decorators (Stage 3) - 드디어 공식 지원
그동안 experimentalDecorators 플래그로 사용하던 데코레이터가 ECMAScript 표준(Stage 3)으로 공식 지원됩니다.
클래스 메서드 데코레이터
// 실행 시간 측정 데코레이터
function logged<t extends="" (...args:="" any[])=""> any>(
originalMethod: T,
context: ClassMethodDecoratorContext
) {
const methodName = String(context.name);
return function (this: any, ...args: Parameters<t>): ReturnType<t> {
console.log(`[${methodName}] 호출됨, 인자:`, args);
const start = performance.now();
const result = originalMethod.apply(this, args);
const end = performance.now();
console.log(`[${methodName}] 완료, 소요시간: ${(end - start).toFixed(2)}ms`);
return result;
};
}
class OrderService {
@logged
processOrder(orderId: string, items: Item[]) {
// 주문 처리 로직
return { success: true, orderId };
}
}
// 출력:
// [processOrder] 호출됨, 인자: ["ord-123", [...]]
// [processOrder] 완료, 소요시간: 45.23ms프로퍼티 데코레이터: 유효성 검사
function validate(min: number, max: number) {
return function (
target: undefined,
context: ClassFieldDecoratorContext
) {
return function (initialValue: number) {
if (initialValue < min || initialValue > max) {
throw new Error(
`${String(context.name)}는 ${min}~${max} 범위여야 합니다`
);
}
return initialValue;
};
};
}
class Product {
@validate(0, 100)
discountRate: number = 10; // OK
@validate(1, 1000000)
price: number = 0; // Error: price는 1~1000000 범위여야 합니다
}주의: 기존 experimentalDecorators와 새 데코레이터는 호환되지 않습니다. NestJS, Angular 등 프레임워크는 아직 기존 방식을 사용하므로 마이그레이션 시 확인이 필요합니다.
2. const Type Parameters - 더 정밀한 타입 추론
Generic 함수에서 const 제약 조건을 추가할 수 있게 되었습니다. 리터럴 타입을 유지하고 싶을 때 유용합니다.
// 기존 방식: 타입이 넓어짐
function getRoutes<t>(routes: T): T {
return routes;
}
const routes1 = getRoutes(["/home", "/about", "/contact"]);
// 타입: string[] (넓은 타입으로 추론)
// TypeScript 5.0: const로 리터럴 유지
function getRoutes<const t="">(routes: T): T {
return routes;
}
const routes2 = getRoutes(["/home", "/about", "/contact"]);
// 타입: readonly ["/home", "/about", "/contact"] (정확한 리터럴)실전 활용: 타입 안전한 라우터
function createRouter<const routes="" extends="" readonly="" string[]="">(
routes: Routes
) {
return {
navigate(to: Routes[number]) {
console.log(`Navigating to ${to}`);
}
};
}
const router = createRouter(["/home", "/profile", "/settings"] as const);
router.navigate("/home"); // OK
router.navigate("/profile"); // OK
router.navigate("/unknown"); // Error: 허용되지 않는 경로3. 성능 대폭 개선
TypeScript 5.0은 내부적으로 네임스페이스에서 모듈로 전환되면서 상당한 성능 향상을 달성했습니다.
| 지표 | 4.9 | 5.0 | 개선율 |
|---|---|---|---|
| 패키지 크기 | 63.8 MB | 37.4 MB | -41% |
| 빌드 시간 (대형 프로젝트) | 45초 | 32초 | -29% |
| IDE 응답 시간 | 200ms | 150ms | -25% |
4. 모든 Enum이 Union Enum으로
이전에는 계산된 값을 가진 enum은 Union 타입으로 취급되지 않았습니다. 5.0부터는 모든 enum이 Union처럼 동작합니다.
enum Status {
Pending = 1,
Active = 2,
Completed = 1 + 2, // 계산된 값
}
function handleStatus(status: Status) {
// 5.0에서는 모든 케이스를 exhaustive하게 체크 가능
switch (status) {
case Status.Pending:
return "대기중";
case Status.Active:
return "진행중";
case Status.Completed:
return "완료";
// default 없어도 에러 없음 (모든 케이스 처리됨)
}
}5. 새로운 설정 옵션
moduleResolution: bundler
// tsconfig.json
{
"compilerOptions": {
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"noEmit": true
}
}Vite, esbuild 같은 번들러와 함께 사용할 때 최적화된 설정입니다. .ts 확장자 임포트도 허용됩니다.
verbatimModuleSyntax
// 타입 전용 import를 명시적으로 표시
import type { User } from "./types"; // 컴파일 시 제거됨
import { validateUser } from "./utils"; // 런타임에 유지됨마이그레이션 체크리스트
- Node.js 버전 확인: 최소 Node 14.17 필요
- 데코레이터 설정 검토: NestJS/Angular 사용 시
experimentalDecorators유지 - tsconfig 업데이트:
target,module설정 검토 - 의존성 호환성: @types 패키지들 최신 버전 확인
# 업그레이드 명령
npm install typescript@5 --save-dev
# 타입 체크 실행
npx tsc --noEmitTypeScript 5.0은 더 안전하고, 더 빠르고, 더 표현력 있는 타입 시스템을 제공합니다. 특히 데코레이터와 const 타입 파라미터는 프레임워크 개발자와 라이브러리 작성자에게 큰 도움이 될 것입니다.