VueJS/VueJS

[VueJS] (Vue 3) - Vuex 타입 추론 설정하기

썸머워즈 2022. 7. 14. 15:42
반응형

본문을 시작하기에 앞 서 아래 링크를 통해 우선 Vuex에서 Typesciprt를 사용하는 방법에 대해 알아온 다음에 이 게시글을 보도록 하자 (아래 게시글을 토대로 작성하였다.)

* [VueJS] (Vue 3) - Vuex를 Typescript로 사용하기

 

[VueJS] (Vue 3) - Vuex를 Typescript로 사용하기

본 글은 vue-cli로 생성한 vue 프로젝트 기준으로 작성하였으며, vuex를 잘 모르겠다면 아래 글을 참고하자. * [VueJS] Vuex 사용하기 (1) - 설치, 세팅 및 기본 사용법 (ft. Composition API) * [Vue..

mine-it-record.tistory.com

 

일단 서론부터 시작하자면

Vuex에서 Typescript를 사용하게 된다면 별다른 설정이 없을 경우 타입 추론이 정상적으로 이루어지지 않는 현상이 발생하게 된다.

 

이 글을 통해 타입 추론 을 설정하는 방법에 대해 알아가 보자.


store/index.ts

import { InjectionKey } from "vue";
import { createStore, useStore as baseUseStore, Store } from "vuex";
import { CreateState, create } from "./modules/create";
import { GameState, game } from "./modules/game";

export interface RootState {
  game: GameState;
  create: CreateState;
}

export const key: InjectionKey<Store<RootState>> = Symbol();

export const store = createStore<RootState>({
  modules: { game, create },
});

// define your own `useStore` composition function
export function useStore() {
  return baseUseStore(key);
}

우선 key를 만들기 위해 InjectionKey를 사용한다.

주입된 값을 동기화해주는 역할인데, 여기서 provide와 inject의 개념을 알고 있다면 좀 더 이해하기 쉽다.

(https://vuejs.org/guide/components/provide-inject.html#provide)

쉽게 말하면, 상위 컴포넌트에서 하위 컴포넌트에 데이터를 제공할 때, 제공한 객체를 문자열로 찾는 것이 아니라 키로 찾을 수 있도록 해주는 것이다.

 

그렇게 우리는 타입을 동기화시켜준다.

그리고 해당 key를 사용하여 Vuex에서 제공하는 useStore 메서드를 확장시켜 사용한다.

main.ts

import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import { store, key } from "./store";

createApp(App).use(store, key).use(router).mount("#app");

main.ts는 설정에 따라 달라질 수는 있는데, 여기서 핵심은 use(store, key) 부분이다.

해당 store/index.ts 경로에서 export해준 store와 key를 사용하도록 명시를 해준다.

App.vue

<script lang="ts">
import { computed, defineComponent } from "vue";
import { useStore } from "@/store";

export default defineComponent({
  name: "App",
  setup() {
    const store = useStore();
    const answer = computed(() => store.state.game.answer);
    
    return { answer };
  },
});
</script>

이제 설정은 끝났으니 실제로 사용해야 하는데, 실제로 사용방법에서 변한 것은 import부분만 변경해서 사용해주면 된다.

import { useStore } from "vuex" >>>>>>>>>>> import { useStore } from "@/store"

vuex에서 사용하던 useStore이 아니라 우리가 직접 설정해준 index.ts에서의 useStore를 바라봐야 한다.

그렇게 되면 아래 이미지처럼 해당 state값의 타입이 추론된 것을 볼 수 있다.

(vuex에 있는 useStore의 경우 무조건 any타입으로 추론되니 이 부분은 이전 게시글을 통해 설명을 해놓았다.)


본 게시글은 공식 문서를 기반으로 직접 작업해서 만든 거라 만약 그대로 했는데 타입 추론이 안된다?

그러면 그다음에 확인해봐야 할 부분이 확장 프로그램을 확인해봐야 한다.

나 역시도 이 부분에서 시간을 굉장히 많이 빼앗겼는데, 

원래 vue2.x버전을 사용했다면 확장 프로그램으로 "Vetur"을 사용했을 텐데 이게 Typescript 지원이 제대로 안되는 거 같다. 

그래서 "Vetur"을 제거하고 "Volar"로 확장 프로그램을 바꿔주면 정상적으로 타입 추론이 되는 것을 볼 수 있다.

해당 관련 글들은 아래 참고 글에 링크를 걸어두었으니 직접 확인해 보길 바란다.


참고: https://vuex.vuejs.org/guide/typescript-support.html#simplifying-usestore-usage

 

TypeScript Support | Vuex

TypeScript Support Vuex provides its typings so you can use TypeScript to write a store definition. You don't need any special TypeScript configuration for Vuex. Please follow Vue's basic TypeScript setup to configure your project. However, if you're writi

vuex.vuejs.org

참고: https://vuejs.org/guide/typescript/overview.html#takeover-mode

 

Using Vue with TypeScript | Vue.js

 

vuejs.org

반응형