타입스크립트의 버전을 4.7에서 5.7로 업데이트한 경험을 정리했습니다.
목차
동기
처음에는 satisfies
키워드를 사용해보고 싶어서 였다. 4.9
버전에서 추가된 키워드인데, 특정 타입을 만족하는지 검사하면서도, 더 구체적인 타입 추론이 가능하도록 돕는 기능이다.
1. satisfies
type Config = {
theme: "light" | "dark";
fontSize: number;
color: "Blue" | "Red" | "Green";
};
const myConfig = {
theme: "dark", // "dark"
fontSize: 16, // number
color: "Orange" // ❌ 에러
extra: "ignored", // ❌ 에러
} satisfies Config;
이처럼 객체가 특정 타입을 충족하는지 확인하면서도, 유니온 타입에 대해서 정밀한 타입 추론이 필요할때 사용하면 좋은 키워드이다. 가끔씩 필요한 경우가 있었지만, 프로젝트에서 사용하는 버전이 4.7이라서 사용할 수 없었다.
2. vue-tsc
vue를 사용하게 되면, 리액트의 tsx, jsx 처럼 vue
라는 특별한 파일을 사용하게 된다. vue파일에서 쓰이는 특정 문법이나 typescript를 사용할 경우에 타입지원을 해주는 플러그인이라고 보면되는데, 2버전 부터 5버전 이상의 타입스크립트를 peer dependency
를 요구했다.
vue
파일을 개발하기 위해선 해당 extension을 설치해야하는데 vscode
는 워크스페이스마다 확장의 특정버전을 설정하는 기능이 없어서 다른 프로젝트를 진행할때는 매번 버전을 재설치 해줘야 하는 불편함이 있었다.
3. 학습 동기부여 및 성능
typescript
에 국한된 이야기는 아니다. 프로젝트에서 의존하고 있는 패키지의 버전은 계속해서 올라가고, 새로운 개발 트렌드 혹은 더 나은 기술이 적용된 업데이트가 계속해서 나오는데, 프로젝트에선 구버전의 패키지에 계속 의존하면 어떻게 될까?
아마 당장 큰 문제는 없을것이다.
하지만 개인적으로는 계속해서 학습하려는 의지가 없어질 것 같다. 새로나온 기능에 대해서 학습하고 프로젝트에도 적용해보고 싶을텐데 프로젝트에서는 해당 기능을 사용할 수 없다면, 배워도 소용없는게 아닐까. 물론 사이드프로젝트에서 써보는것도 의미있을 수 있지만, 실제로 업무하면서 하는 경험이 동기부여가 확실했었다.
그리고 프로젝트도 점점 maintain mode
에 들어간 패키지에 의존하거나 혹은 deprecated
된 패키지에 의존하게 될것이다. 나중에는 업데이트 하고 싶어도 여러 의존성 때문에 골치 아플꺼다.
또 한가지는 버전만 업데이트 해도 프로젝트의 성능 향상을 꾀할 수 있다는 점이다. 실제로 이번 버전 업데이트 이후, typescript 관련 기능이 체감될 정도로 빨라졌다.
과정
언뜻 생각하기에 typescript
는 컴파일 타임에 동작하는 패키지이기 때문에 빌드 결과물에는 영향이 없을거라 예상했고,
타입스크립트 디자인 방향성을 살펴보았을때도, 크게 영향받는 점을 없을 것 같았지만, 몇 가지 체크를 해보았다.
11. Do not cause substantial breaking changes from TypeScript 1.0.
1. 고려한 점
- target 옵션이 달라지는가?
- 데코레이터 같은 실험적 기능을 사용하는가?
- javascript에는 없는 typescript 고유 문법을 사용하는가
다행히도 모두 해당사항이 없었다.
2. 변경
typescript
,vue-tsc
버전 업데이트 및vue(vscode extension)
버전 업데이트- tsconfig의
moduleResolution
기존node
에서bundler
로 변경
버전 업데이트야 당연하지만 moduleResolution
의 경우에는 5.0버전에서 추가된 옵션인데, 기존 버전에서는 package.json
의 exports
필드를 무시했었다. 하지만 번들러에서는 해당 옵션을 통해 모듈의 위치를 파악했기때문에 typescript
와 모듈의 해석 방식이 다를 수 있었다. 하지만 moduleResolution
옵션에 bundler
값이 추가됨에 따라 번들러와 동일한 방식으로 모듈을 해석할 수 있게 되었다.
문제
1. eslint
버전
생각해보면 당연하지만 깜빡했던 부분이 eslint
와 typescript-eslint
버전을 업데이트를 안해줬다. 그래서 콘솔에 warning이 뜨고 있길래 부랴부랴 추가적으로 업데이트를 해줬다.
2. node
버전
근데 또 연쇄적으로 node버전에도 문제가 발생했다. 빌드에러가 발생해서 살펴보니 typescript-eslint
에서 요구하는 node버전이 18이상이었다.
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
하지만 빌드용 이미지의 노드버전이 16이어서 빌드에러가 발생했다. 사실 node16은 작년에 지원종료한 버전이기때문에 이번 기회에 노드도 18버전으로 업데이트를 진행했다.
이 과정에서 structuredClone
은 node18부터 지원됐다라는 점과 node16은 작년에 지원 종료 됐다는 점을 새로 알게 됐다.
결과
이렇게 무사히(?) typescript
, vue-tsc
, eslint
, typescript-eslint
업데이트 및 pipeline 노드 버전 업데이트를 진행했다. 이렇게 업데이트를 진행하고 보니 앞으로는 typescript
를 쓰더라도 최대한 javascript
에서도 지원하는 문법을 사용하는게 좋을것 같다는 생각을 가지게 됐다.
그리고 5.8 버전부터는 —erasableSyntaxOnly 플래그를 지원한다고 한다. 해당 플레그를 사용한다면, 추후에 타입스크립트 버전을 업데이트 할때 크게 신경쓸 일은 없을것 같다.