🚀 TypeScript의 진화, 한눈에 파악하기
TypeScript는 끊임없이 발전하며 개발자에게 더 나은 타입 안정성과 편의성을 제공합니다.
ECMAScript의 최신 기능을 발 빠르게 지원하는 동시에, 더욱 정교한 타입 추론과 강력한 도구로 무장하고 있죠.
이 글에서는 TypeScript 5.0부터 5.8까지의 여정을 따라가며, 개발자라면 꼭 알아야 할 핵심 변경 사항들을 버전별로 알기 쉽게 정리했습니다.
🎨 TypeScript 5.0: 데코레이터의 귀환과 모듈 혁신
1. ECMAScript 데코레이터 (Decorators)
가장 큰 변화입니다. 클래스, 메서드, 프로퍼티 등을 선언적으로 꾸며주는 데코레이터가 ECMAScript 표준에 맞춰 재탄생했습니다. 기존의 실험적 데코레이터와 호환되지 않으므로 마이그레이션이 필요하지만, 더욱 강력하고 표준적인 메타 프로그래밍이 가능해졌습니다.
function loggedMethod(originalMethod: any, context: ClassMethodDecoratorContext) {
const methodName = String(context.name);
function replacementMethod(this: any, ...args: any[]) {
console.log(`LOG: Entering method '${methodName}'.`);
const result = originalMethod.call(this, ...args);
console.log(`LOG: Exiting method '${methodName}'.`);
return result;
}
return replacementMethod;
}
class Person {
name: string;
constructor(name: string) {
this.name = name;
}
@loggedMethod
greet() {
console.log(`Hello, my name is ${this.name}.`);
}
}
new Person("Alice").greet();
2. `const` 타입 매개변수 (const Type Parameters)
제네릭 함수에서 `const` 한정자를 사용하여 타입 매개변수를 추론할 때, 최대한 불변성을 유지하며 좁은 타입으로 추론하도록 강제할 수 있습니다. 이는 가변 인자나 리터럴 타입 배열을 다룰 때 매우 유용합니다.
3. 새로운 모듈 해석 옵션: `--moduleResolution bundler`
Vite, esbuild, Webpack 등 최신 번들러의 동작 방식을 더 정확하게 흉내 내는 새로운 모듈 해석 전략이 추가되었습니다. 이로 인해 실제 번들링 환경과 타입스크립트의 타입 확인 환경 간의 불일치가 크게 줄어듭니다.
✨ TypeScript 5.1: 편의성 및 JSX 개선
1. `undefined`를 반환하는 함수의 암시적 리턴 허용
이전에는 `undefined`를 반환 타입으로 명시한 함수도 `return;` 또는 `return undefined;`를 반드시 포함해야 했습니다. 이제는 아무런 `return` 문이 없어도 오류가 발생하지 않아 `void`와 동작이 통일되었습니다.
2. Getter/Setter의 타입 불일치 허용
클래스의 Getter와 Setter가 서로 관련 없는 타입(subtype 관계가 아닌)을 가질 수 있게 되었습니다. 예를 들어, DOM의 `style` 프로퍼티처럼 값을 설정할 때는 문자열을 받지만, 읽을 때는 객체(`CSSStyleDeclaration`)를 반환하는 경우를 더 정확하게 모델링할 수 있습니다.
🛠️ TypeScript 5.2: `using` 선언과 데코레이터 메타데이터
1. `using` 선언 및 명시적 리소스 관리 (Explicit Resource Management)
ECMAScript의 새로운 기능인 명시적 리소스 관리를 지원합니다. `using` 키워드를 사용하면 파일 핸들, 네트워크 연결 등 스코프를 벗어날 때 자동으로 정리(dispose)되어야 하는 리소스를 더 안전하고 간결하게 관리할 수 있습니다. `try...finally` 블록의 번거로움을 크게 줄여줍니다.
function doSomeWork() {
using file = getFileHandle(); // 스코프 종료 시 자동으로 file.dispose() 호출
// ... file 사용 ...
}
2. 데코레이터 메타데이터 (Decorator Metadata)
데코레이터가 클래스에 메타데이터를 쉽게 생성하고 소비할 수 있는 표준화된 방법을 제공합니다. 데코레이터 컨텍스트 객체에 `metadata` 속성이 추가되어, 데코레이터 간 정보 공유나 프레임워크 수준의 기능 구현이 용이해집니다.
🔍 TypeScript 5.3: 타입 좁히기(Narrowing) 능력 강화
1. `switch (true)` 구문을 통한 타입 좁히기
`switch (true)` 패턴 내부의 각 `case` 조건문을 분석하여 타입을 더 정확하게 좁힐 수 있게 되었습니다. 복잡한 조건 분기를 더 명확하고 타입-세이프하게 작성할 수 있습니다.
2. Import Attributes 지원
ECMAScript의 `import` 구문에 추가 정보를 제공하는 `with` 절(Import Attributes)을 지원합니다. 주로 JSON 모듈을 안전하게 가져올 때 사용됩니다.
import obj from "./something.json" with { type: "json" };
🧠 TypeScript 5.4: 클로저와 `NoInfer` 타입
1. 클로저 내에서의 타입 좁히기 유지
함수 클로저 내에서 외부 변수의 타입이 더 정확하게 유지됩니다. 마지막으로 할당된 시점 이후에 생성된 클로저에서는, 해당 변수의 좁혀진 타입이 그대로 유지되어 불필요한 오류가 줄어듭니다.
2. `NoInfer` 유틸리티 타입
제네릭 타입 추론을 제어할 수 있는 `NoInfer` 유틸리티 타입이 추가되었습니다. 특정 매개변수가 타입 추론에 기여하는 것을 막고 싶을 때 사용하여, 원치 않는 타입 확장을 방지하고 더 정확한 타입 검사를 유도할 수 있습니다.
3. `Object.groupBy`와 `Map.groupBy` 지원
배열과 같은 iterable 객체를 특정 기준에 따라 그룹화하는 새로운 ECMAScript 표준 메서드 `Object.groupBy`와 `Map.groupBy`에 대한 타입 정의가 추가되었습니다.
🚀 TypeScript 5.5: 타입 추론의 비약적 발전
1. 타입 단언(Type Predicates) 자동 추론
이 버전의 하이라이트입니다. `.filter()`와 같은 배열 메서드에서 타입 가드 함수를 명시적으로 작성하지 않아도, TypeScript가 자동으로 타입 단언을 추론합니다. `filter(Boolean)`이나 `filter(x => x != null)`과 같은 코드가 이제 `undefined`나 `null`을 제거하고 타입을 정확하게 좁혀줍니다.
// 이전 버전에서는 (Bird | undefined)[] 타입이었음
// TS 5.5부터는 Bird[] 타입으로 정확하게 추론됨!
const birds: Bird[] = countries
.map(country => nationalBirds.get(country))
.filter(bird => bird !== undefined);
2. JSDoc에서 `@import` 태그 지원
JavaScript 파일의 JSDoc 주석 내에서 `@import` 태그를 사용하여 타입 정보를 가져올 수 있게 되어, 런타임에 영향을 주지 않고 타입 검사를 강화할 수 있습니다.
3. 정규 표현식 구문 검사
정규 표현식 리터럴의 구문을 검사하여 잘못된 패턴이나 존재하지 않는 역참조 같은 흔한 실수를 컴파일 타임에 잡아줍니다.
🛡️ TypeScript 5.6: 코드 안정성 강화
1. `Truthy` 및 `Nullish` 검사 강화
조건문에서 항상 `true` 또는 `false`로 평가되는 표현식을 감지하여 오류를 발생시킵니다. 예를 들어, `if (/regex/)` 나 `if (x => 0)` 와 같이 의도치 않게 항상 참이 되는 코드를 잡아내 버그를 예방합니다.
2. `--noUncheckedSideEffectImports` 옵션
존재하지 않는 모듈을 사이드 이펙트를 위해 `import`하는 경우, 이전에는 조용히 무시되었지만 이제는 이 옵션을 통해 오류로 만들 수 있습니다. 경로 오타 등으로 인한 잠재적인 문제를 방지합니다.
🌐 TypeScript 5.7: 최신 JS 런타임 대응
1. `assert`에서 `with`로: Import Attributes 문법 업데이트
TC39 위원회에서 Import Assertions가 Import Attributes로 변경되면서 `assert` 키워드가 `with` 키워드로 변경되었습니다. TypeScript도 이에 맞춰 문법을 업데이트했으며, 이전 `assert` 문법은 점차 사용이 중단될 예정입니다.
2. 조건부 타입 내 타입 좁히기 지원
제네릭과 조건부 타입을 사용하는 함수에서 `return` 문을 분석할 때, 제네릭 타입을 더 정확하게 좁혀서 추론합니다. 이를 통해 이전에는 타입 단언(`as`)이 필요했던 많은 복잡한 제네릭 함수를 타입-세이프하게 작성할 수 있게 되었습니다.
⚡ TypeScript 5.8: 더 똑똑하고 빨라진 컴파일러
1. `return` 표현식 내 분기문의 세분화된 검사
함수의 `return`문 안에 있는 삼항 연산자와 같은 조건 표현식의 각 분기를 개별적으로 검사합니다. 이전에는 `any` 타입 등으로 인해 놓칠 수 있었던 버그를 이제는 컴파일 타임에 정확히 잡아냅니다.
2. `--module nodenext`에서 ES 모듈 `require()` 지원
Node.js 22부터 지원되는 CommonJS 모듈에서 ES 모듈을 `require()`하는 기능을 TypeScript도 `--module nodenext` 설정 하에 지원합니다. 라이브러리 제작자들이 듀얼 패키징의 고통에서 벗어날 수 있는 중요한 업데이트입니다.
🎯 결론: TypeScript, 멈추지 않는 진화
TypeScript 5.x 버전대는 개발자 경험(DX)과 타입 시스템의 정확성이라는 두 마리 토끼를 모두 잡기 위해 부단히 노력해왔습니다.
최신 JavaScript 표준을 빠르게 흡수하는 것은 물론, 더 스마트한 추론과 강력한 에러 감지 기능으로 무장했죠.
프로젝트에 최신 버전을 도입하여 이러한 새로운 기능들을 적극적으로 활용해 보시길 바랍니다!
🏷️ 관련 태그
'TypeScript' 카테고리의 다른 글
React Hook Form + Zod 스키마 검증 완전 정복: 타입 안전한 폼 구현의 모든 것 (0) | 2025.06.06 |
---|---|
Next.js 13 App Router 마이그레이션 완전 가이드: Pages에서 App으로 안전하게 전환하기 (0) | 2025.06.05 |
Next.js의 Image 컴포넌트 가이드 (0) | 2025.04.29 |
브레드크럼(Breadcrumb): 사용자 경험을 향상시키는 네비게이션 요소 (1) | 2025.04.15 |
Next.js에서 class-variance-authority(CVA)로 재사용 가능한 UI 컴포넌트 만들기 (0) | 2025.04.14 |