10 점진적인 타입스크립트 적용 방식 1단계 - 라우터, HOC, 유틸 함수

source: categories/study/vue-beginner-lv5/vue-beginner-lv5_9-01.md

10.1 프로젝트 빌드 에러 해결


yarn serve

에러는 많이 발생하지만 서버는 실행되는 상태이다.
강의에서는 localhost:8080으로 들어갔을 때, 페이지가 정상적으로 나오고 기능도 제대로 된다.
하지만, 내 로컬에선 안된다.
페이지도 안 뜨고..
여튼 버전 차이가 문제인거 같음.

여튼 강의에선 다시 build를 실행


yarn build

 ERROR  Build failed with errors.

당연히 빌드 에러가 발생한다.
실행상 에러와 빌드상 에러가 일치한다.

Note

타입스크립트 버전업하면서 훨씬 더 엄격해진건가?
강의에선 3점대 버전 때는 빌드 때만 에러발생하게하고, 그냥 개발시엔 에러가 발생해도 실행되게한거보면…

여튼 빌드 에러나는 것은 확인했기 때문에, 다시 개발서버를 실행해보도록 하자.


yarn serve

10.1.1 main.ts 파일에서 발생하는 에러


TS7016: Could not find a declaration file for module './routes/index.js'. 
'/Users/.../vue-news-ts/src/routes/index.js' implicitly has an 'any' type.

# implicitly has an 'any' type.
# 타입에 any라도 명시되어있어야하는데 any 타입도 없다.
# 즉, 이는 strict(엄격한) 옵션이 켜져있기 때문에 발생하는 에러이다. - 물론 타입을 명시해 해결하는 것이 더 좋지만 일단..
# 점진적 적용을 위해 tsconfig.js, 즉, 타입스크립트 설정 파일에 있는 strict 옵션을 낮추고 시작을 해보도록 하겠다.

아래와 같이 옵션을 추가해준다.
어차피 strict: false를 주면, noImplicityAny도 자동으로 false가 되지만, 일단 명시적으로 하기 위해 적었다.



{
    "strict": false,
    "noImplicitAny": false,
}


다시 실행해보자.


yarn serve

ERROR in /Users/hyungjulee/vue-training-lv5/vue-news-ts/src/main.ts(9,3):
9:3 No overload matches this call.
  Overload 1 of 3, '(options?: ThisTypedComponentOptionsWithArrayProps<Vue, object, object, object, never>): CombinedVueInstance<Vue, object, object, object, Record<...>>', gave the following error.
    Argument of type '{ router: any; store: any; render: (h: CreateElement) => VNode; }' is not assignable to parameter of type 'ThisTypedComponentOptionsWithArrayProps<Vue, object, object, object, never>'.
      Object literal may only specify known properties, and 'router' does not exist in type 'ThisTypedComponentOptionsWithArrayProps<Vue, object, object, object, never>'.
  Overload 2 of 3, '(options?: ThisTypedComponentOptionsWithRecordProps<Vue, object, object, object, object>): CombinedVueInstance<Vue, object, object, object, Record<...>>', gave the following error.
    Argument of type '{ router: any; store: any; render: (h: CreateElement) => VNode; }' is not assignable to parameter of type 'ThisTypedComponentOptionsWithRecordProps<Vue, object, object, object, object>'.
      Object literal may only specify known properties, and 'router' does not exist in type 'ThisTypedComponentOptionsWithRecordProps<Vue, object, object, object, object>'.
  Overload 3 of 3, '(options?: ComponentOptions<Vue, DefaultData<Vue>, DefaultMethods<Vue>, DefaultComputed, PropsDefinition<Record<string, any>>, Record<...>>): CombinedVueInstance<...>', gave the following error.
    Argument of type '{ router: any; store: any; render: (h: CreateElement) => VNode; }' is not assignable to parameter of type 'ComponentOptions<Vue, DefaultData<Vue>, DefaultMethods<Vue>, DefaultComputed, PropsDefinition<Record<string, any>>, Record<...>>'.
      Object literal may only specify known properties, and 'router' does not exist in type 'ComponentOptions<Vue, DefaultData<Vue>, DefaultMethods<Vue>, DefaultComputed, PropsDefinition<Record<string, any>>, Record<...>>'.
     7 | 
     8 | new Vue({
  >  9 |   router,
       |   ^
    10 |   store,
    11 |   render: (h) => h(App),
    12 | }).$mount("#app");
Version: typescript 4.1.6

위 에러 하나만 남고 나머진 해결된 모습이다.
routes/index.js 파일에서 발생한 에러인듯 하다.

  • 자바스크립트 파일을 타입스크립트에서 인식할 수 있도록 하려면 저희가 배웠던 속성 중에 allowJs라는 속성을 사용하면된다.

10.1.2 allowJs



{
    "allowJs": true,
}


강의에선 main.tsrouter에 생기던 에러가 해결되었지만,
내 로컬에선 여전히 router에 에러가 남아있다.

버전업 때문에 그런거같은데..

강의 시점 때 vue-router, vuex 다 3버전 대였는데, 지금 내가 실습하는 순간엔 4점대 버전이다.
버전업 때문에 그런거같음..

Note

10.1 프로젝트 빌드 에러 해결 (버전업 때문인지 여전히 router 에러 발생)

10.1.3 지금 현재 강의와 상이한 부분이 주버전 업데이트로인해 발생하는 문제인가?

10.1.3.1 의심되는 모듈 버전

  1. vue-router: 강의시점 3.4.9, 실습시점 4.0.12
  2. vuex: 강의시점 3.6.0, 실습시점 4.0.2
  3. typescript: 강의시점 3.9.3, 실습시점 4.1.5

Note

헐.. 맞네..
위에 3개 라이브러리 버전을 강의시점과 일치 시켰더니 에러가 발생하지 않았다.

좀 더 조사는 필요

10.1.3.2 결론

즉, 이는 typescript의 주버전 업데이트가 원인이었다기보단 vue-router, vuex 라이브러리의 주버전이 업데이트되면서
각 라이브러리의 코드 작성방식에 무언가 변화가 있었던 것 같다.
그로인해 import, export시에 기존과는 다른 작성방식을 했어야됐던거 같고..

애초에 강의시점의 코드내용을 클론받아 한거기 때문에 그 시점 라이브러리 버전들은 다 예전꺼였지만,
지금 새로 프로젝트를 설치해서 할 땐 버전업데이트가 되어있으므로,
여튼..
버전 업데이트가 이번 원인이 맞았네.

일단 그럼 이 강의시점 버전으로 진행하자..

Note

10.1.3.3 프로젝트 빌드 에러 해결 (강의시점 버전과 일치)

10.2 App.vue에 타입스크립트 적용 및 strict 옵션 참고 사항

Note

10.2.1 App.vue에 타입스크립트 적용 및 strict 옵션 참고 사항

10.3 유틸성 파일에 TS 적용 및 주요 TS 적용 포인트 안내

  • HOC 컴포넌트 (지금 예제 코드에서 코드량 줄일려고 공통 컴포넌트 통일화한 부분이 HOC 컴포넌트임)
    • createListView
Note

10.3.1 유틸성 파일에 TS 적용 및 주요 TS 적용 포인트 안내

10.4 라우터 파일에 TS 적용 및 라이브러리 내부 타입 선언 파일 설명

  1. TS2554: Expected 0-1 arguments, but got 2.
    • 인자는 0~1개만 있으면되는데, 2개가 있다는 뜻.
  2. beforeEnter
    • 네비게이션 가드

export type NavigationGuard<V>
Alias for:
(to: Route, from: Route, next: NavigationGuardNext<V>) => any
vue-router

위와 같이 beforeEnter 네비게이션 가드에 마우스 커서를 올리면 해당 메소드에 대한 설명이 뜬다.
첫번째 인자에는 어떤 유형의 값이, 두번째 인자에는 어떤 유형의 값이 들어오는지에 대한 설명이 다 나와있다.
이런 것들을 사용해 각 인자의 타입을 정의한다.

첫번째 인자와 두번째 인자에 vue-router 라이브러리에서 제공하는 Route 타입을 정의해준다.

일반적으로 저희가 라이브러리를 사용하면, 해당 라이브러리 안에 타입을 잘 정의해놓은 코드가 있다.

  1. @types라는 라이브러리 또는
  2. 잘 만들어진 라이브러리는 그 라이브러리 내부에 index.d.ts가 있다.

위와 같이 axios 라이브러리를 봐도 index.d.ts 파일이 있다.
index.d.ts는 타입스크립트에서 사용하는 타입을 선언한 파일이라고 보면된다.
때문에 axios@types/axios 라이브러리를 따로 설치를 안해도된다.

10.4.1 vue 타입 정의 관점에서의 취약점 - vue 3에서 이런 취약점 개선

  • vue 라이브러리가 타입정의, 타입 시스템을 고려하고 만든 라이브러리가 아니기 때문에 타입 정의 관점에서 취약점이 있었다.
  • 이러한 취약점이 vue 3로 넘어오면서 전체적으로 타입 시스템을 잘 활용할 수 있게 개선되었다.

현재는 가벼운 수준으로만 타입 정의가 되어있는데, vue3를 나중에 보시게되면 내부적으로 지원하는 타입들이 되게 많아지면서 저희가 컴포넌트 레벨에서 가져다 쓸 수 있는 타입들이 많아지게된다.
그렇다고해서 vue2에서 타입스크립트를 전혀 못쓴다. 그런 수준은 아니다.

10.4.2 타입 적용 꿀팁 - 마우스 커서 올려놓을 때 뜨는 힌트를 활용!!!

마우스 커서 올려놓을때 뜨는 힌트를 적극 활용!

Note

10.4.3 라우터 파일에 TS 적용 및 라이브러리 내부 타입 선언 파일 설명

10.5 HOC 파일에 TS 적용 및 라우터 네비게이션 함수 로직 개선

  • vue에선 render 함수를 활용해 화면을 그려줄 수 있다.
Note

10.5.1 HOC 파일에 TS 적용 및 라우터 네비게이션 함수 로직 개선

10.5.2 파일 경로 의문점

위와 같이 경로를 줬을 땐

TS7016: Could not find a declaration file for module '../views/CreateListView'. 
'C:/workspace/.../src/views/CreateListView.js' implicitly has an 'any' type.

이런 에러가 뜨면서

이렇게 주니깐 에러 안뜨는건 뭐지?
CreateListView.js 파일을 CreateListView.ts로..
즉, 타입스크립트 파일로 바꾸니까 갑자기 이러네 음..