TypeScript 6.0 발표
(devblogs.microsoft.com)- JavaScript 기반 현재 코드베이스의 마지막 릴리스이자, Go로 작성된 네이티브 포트인 TypeScript 7.0으로의 전환을 준비하는 브릿지 릴리스
-
this를 사용하지 않는 함수의 컨텍스트 민감도 완화,#/로 시작하는 subpath imports 지원 등 타입 추론과 모듈 해석 개선 포함 -
strict기본값true전환,target기본값es2025,types기본값[]등 컴파일러 옵션 기본값의 대폭 현대화 - ES5 타겟, AMD/UMD/SystemJS 모듈,
--baseUrl,--moduleResolution node10등 레거시 옵션 대거 폐기(deprecation) - Temporal API, Map의
getOrInsert/getOrInsertComputed,RegExp.escape등 최신 ECMAScript Stage 4 제안의 타입 지원 추가
TypeScript 6.0의 위치
- 현재 JavaScript 코드베이스 기반의 마지막 릴리스로, TypeScript 7.0(Go 네이티브 포트)으로의 전환을 위한 브릿지 역할
- TypeScript 7.0은 네이티브 코드와 공유 메모리 멀티스레딩을 활용하며, 이미 완성에 매우 근접한 상태
- 6.0의 대부분의 변경사항은 7.0 채택을 정렬하고 준비하기 위한 것
- TypeScript 7.0은 VS Code 확장이나 npm 패키지로 미리 체험 가능
Beta 및 RC 이후 변경사항
- 제네릭 호출(특히 제네릭 JSX 표현식)에서 함수 표현식의 타입 체킹 조정 — 기존 코드에서 더 많은 버그를 잡지만, 일부 제네릭 호출에 명시적 타입 인수가 필요할 수 있음
-
import()호출에서도 import assertion 구문(assert)의 폐기 확장 적용 - DOM 타입 업데이트 — 최신 웹 표준 반영, Temporal API 관련 조정 포함
this를 사용하지 않는 함수의 컨텍스트 민감도 완화
- TypeScript는 타입 추론 시 명시적 타입이 없는 매개변수를 가진 함수를 컨텍스트 민감 함수(contextually sensitive function) 로 분류하고, 추론 순서에서 후순위로 처리
- 메서드 구문(method syntax)으로 작성된 함수는 암묵적
this매개변수가 있어 화살표 함수와 달리 항상 컨텍스트 민감으로 처리되었음- 이로 인해 객체 리터럴 내 메서드 순서에 따라 타입 추론이 실패하는 경우 발생
- TypeScript 6.0에서는
this가 실제로 사용되지 않는 함수는 컨텍스트 민감으로 간주하지 않음- 해당 함수들은 타입 추론에서 우선순위가 높아져, 메서드 순서에 관계없이 정상 추론
- Mateusz Burzyński의 기여로 구현
#/로 시작하는 Subpath Imports 지원
- Node.js의 subpath imports 기능은 패키지 내부 모듈에 대한 별칭을
package.json의imports필드로 정의하는 것 - 기존에는
#뒤에 반드시 문자가 필요해#/로 시작하는 경로를 사용할 수 없었음- 번들러에서
@/접두사 컨벤션에 익숙한 개발자들에게 혼란 유발
- 번들러에서
- Node.js가 최근
#/로 시작하는 subpath imports를 지원하기 시작-
"#/*": "./dist/*"형태의 간결한 매핑 가능
-
- TypeScript 6.0은
--moduleResolution nodenext및bundler옵션에서 이를 지원 - magic-akari의 기여로 구현
--moduleResolution bundler와 --module commonjs 조합 허용
- 기존에는
--moduleResolution bundler가--module esnext또는--module preserve에서만 사용 가능 -
--moduleResolution node(node10) 폐기로 인해, 이 새로운 조합이 많은 프로젝트의 가장 적합한 업그레이드 경로 - 장기적으로는
--module preserve+--moduleResolution bundler또는--module nodenext로의 마이그레이션 권장
--stableTypeOrdering 플래그
- TypeScript 내부에서 타입에 할당되는 타입 ID는 처리 순서에 따라 결정되며, 이를 기반으로 유니온 타입을 정렬
- 선언 순서에 따라 선언 emit 결과가 달라지는 예측 불가능한 현상 발생 가능
- TypeScript 7.0은 병렬 타입 체킹을 도입하므로, 비결정적 ID 할당 문제를 해결하기 위해 콘텐츠 기반의 결정적 정렬 알고리듬 사용
- 예:
100 | 500이 항상 동일한 순서로 출력
- 예:
-
--stableTypeOrdering플래그를 6.0에서 활성화하면 7.0의 타입 정렬 동작과 일치시켜 두 코드베이스 간 차이를 줄일 수 있음- 타입 체킹에 최대 25% 성능 저하 발생 가능
- 추론 차이로 인한 타입 오류 발생 시, 명시적 타입 인수나 변수 어노테이션 추가로 해결
- 6.0에서 7.0으로의 마이그레이션 진단용으로만 의도된 플래그, 장기 사용은 비권장
es2025 옵션 (target과 lib)
- ES2025에는 새로운 JavaScript 언어 기능은 없지만, 빌트인 API 타입(예:
RegExp.escape) 추가 -
esnext에 있던Promise.try,Iterator메서드,Set메서드 등이es2025로 이동 - Kenta Moriuchi의 기여로 구현
Temporal API 타입 지원
- Stage 4에 도달한 Temporal 제안의 빌트인 타입을 TypeScript 6.0에 포함
-
--target esnext또는"lib": ["esnext"](또는 세분화된esnext.temporal)로 사용 가능 -
Temporal.Now.instant().subtract(),.add()등의 API를 타입 안전하게 사용 가능 - 이미 여러 런타임에서 사용 가능하며, Stage 4로 공식 JavaScript 언어의 일부
- Renegade334의 기여로 구현
Map의 "upsert" 메서드 타입 지원 (getOrInsert / getOrInsertComputed)
- Map에서 키 존재 여부를 확인하고 없으면 기본값을 설정하는 반복적인 패턴을 간소화
- ECMAScript의 "upsert" 제안이 Stage 4에 도달,
Map과WeakMap에 두 가지 새 메서드 추가-
getOrInsert: 키가 없으면 지정한 기본값을 삽입하고 반환 -
getOrInsertComputed: 기본값 생성 비용이 클 때 콜백을 통해 지연 계산- 콜백은 키를 인수로 받아, 키 기반 기본값 생성에도 활용 가능
-
-
esnextlib에 추가되어 TypeScript 6.0에서 즉시 사용 가능 - Renegade334의 기여로 구현
RegExp.escape
- 정규식 내 특수 문자를 이스케이프하는
RegExp.escape함수가 Stage 4에 도달 -
es2025lib에 포함되어 TypeScript 6.0에서 사용 가능 - Kenta Moriuchi의 기여로 구현
dom lib에 dom.iterable 및 dom.asynciterable 통합
- 기존에는
NodeList,HTMLCollection등에서 이터레이션을 사용하려면"lib": ["dom", "dom.iterable"]을 명시해야 했음 - TypeScript 6.0에서는
lib.dom.iterable.d.ts와lib.dom.asynciterable.d.ts의 내용이lib.dom.d.ts에 완전 통합-
dom.iterable,dom.asynciterable은 여전히 참조 가능하나 빈 파일
-
- 모든 주요 최신 브라우저가 해당 기능을 지원하므로, 흔한 혼동 포인트를 제거하는 편의 개선
주요 기본값 변경
-
strict기본값true: 대부분의 신규 프로젝트가 strict 모드를 원하므로, 기존false에 의존했던 프로젝트는 명시적으로"strict": false설정 필요 -
module기본값esnext: ESM이 지배적 모듈 형식이 된 현실 반영 -
target기본값 최신 ES 버전(현재es2025): 에버그린 런타임이 보편화되어 구버전 트랜스파일이 불필요 -
noUncheckedSideEffectImports기본값true: 사이드 이펙트 전용 임포트의 오타 감지 지원 -
libReplacement기본값false: 불필요한 모듈 해석 실패 및 감시 대상 증가를 방지하여 기본 성능 개선
rootDir 기본값 .로 변경
- 기존에는 미지정 시 모든 비선언 입력 파일의 공통 디렉토리를 추론하여 결정
- 프로젝트에 파일이 속하는지 판단하려면 해당 프로젝트를 로드·파싱해야 하는 문제
- TypeScript 6.0에서는 기본값이
tsconfig.json이 위치한 디렉토리로 고정 -
tsconfig.json보다 깊은 위치에 소스 파일이 있는 경우"rootDir": "./src"등을 명시적으로 설정 필요- 미설정 시
./dist/src/index.js처럼 의도하지 않은 출력 구조 발생 가능
- 미설정 시
types 기본값 []로 변경
- 기존에는
node_modules/@types내 모든 패키지를 자동 포함하여 빌드 시간에 큰 오버헤드- 일반적인 저장소에서 수백 개의
@types패키지가 전이적으로 포함되는 경우 다수
- 일반적인 저장소에서 수백 개의
- TypeScript 6.0에서 기본값
[](빈 배열)로 변경, 불필요한 선언 파일 로드 방지 - 실제 빌드 시간 20~50% 개선 사례 확인
- 대부분의 프로젝트에서
"types": ["node"]또는"types": ["node", "jest"]등의 명시적 설정 필요-
"types": ["*"]로 기존 동작 복원 가능
-
폐기(Deprecation) 항목
target: es5 폐기
- ES5 타겟은 IE 퇴역 및 에버그린 브라우저 보편화로 사용 사례가 거의 없음
- 최소 타겟이 ES2015로 변경, ES5 출력이 필요하면 외부 컴파일러 사용 권장
--downlevelIteration 폐기
- ES5 emit에서만 효과가 있었으므로, ES5 타겟 폐기에 따라 목적 상실
--moduleResolution node(node10) 폐기
- Node.js 10의 모듈 해석 알고리듬을 반영한 것으로, 최신 Node.js 동작과 불일치
-
nodenext(Node.js 직접 타겟) 또는bundler(번들러/Bun 사용)로 마이그레이션 권장
AMD, UMD, SystemJS 모듈 값 폐기
-
--module amd,--module umd,--module systemjs,--module none모두 미지원 - ESM이 브라우저와 Node.js에서 보편적으로 지원되므로, 번들러 또는 ESM 타겟으로 전환 필요
--baseUrl 폐기
- 주로
paths의 접두사로 사용되었으나, 모듈 해석의 룩업 루트로도 동작하여 의도치 않은 경로 해석 문제 유발 -
baseUrl을 제거하고paths항목에 직접 접두사를 추가하는 것으로 마이그레이션- 예:
"@app/*": ["app/*"]→"@app/*": ["./src/app/*"]
- 예:
--moduleResolution classic 폐기
- TypeScript의 원래 모듈 해석 알고리듬으로, 현재 모든 실용적 사례는
nodenext또는bundler로 대체 가능
esModuleInterop false 및 allowSyntheticDefaultImports false 폐기
- 두 옵션을
false로 설정하는 것이 불가해져, 안전한 interop 동작이 항상 활성화 -
import * as express from "express"→import express from "express"로 조정 필요
--alwaysStrict false 폐기
- 모든 코드가 JavaScript strict mode로 간주,
await,static,private등을 일반 식별자로 사용하는 코드는 이름 변경 필요
outFile 폐기
- 여러 입력 파일을 하나로 결합하는 기능이었으나, Webpack, Rollup, esbuild, Vite 등 외부 번들러로 대체
- TypeScript의 핵심 역할인 타입 체킹과 선언 emit에 집중하기 위한 결정
레거시 module 구문(네임스페이스 선언) 폐기
-
module Foo { ... }구문이 하드 폐기,namespace Foo { ... }사용 필요 -
declare module "some-module" { ... }형태의 앰비언트 모듈 선언은 그대로 지원 - ECMAScript의
module블록 제안과의 충돌 방지 목적
Import asserts 키워드 폐기
-
import ... asserts { type: "json" }→import ... with { type: "json" }으로 변경 필요 - import assertions 제안이 import attributes 제안(
with키워드) 으로 변경된 것에 따른 조치
no-default-lib 디렉티브 폐기
-
/// <reference no-default-lib="true"/>더 이상 미지원,--noLib또는--libReplacement사용 권장
tsconfig.json 존재 시 커맨드라인 파일 지정 오류
-
tsc foo.ts실행 시 같은 디렉토리에tsconfig.json이 있으면 오류 발생 -
--ignoreConfig플래그로 명시적으로 무시 가능
TypeScript 7.0 준비
- 6.0에서 폐기된 옵션은
"ignoreDeprecations": "6.0"설정으로 오류 없이 계속 사용 가능하나, 7.0에서는 완전히 제거 -
ts5to6 도구를 통해
baseUrl,rootDir등의 자동 조정 가능 - TypeScript 7.0은 수 개월 내 릴리스 예정이며, Microsoft 내외부의 대규모 코드베이스에서 이미 폭넓게 채택 중
- 네이티브 프리뷰 nightly 빌드와 VS Code 확장을 통해 피드백 권장