LoginSignup
4
1

More than 3 years have passed since last update.

VueのOptionsAPI導入して「Property 'hoge' does not exist on type 'CombinedVueInstance<Vue…」みたいなエラーが出る

Last updated at Posted at 2020-08-03

問題提起

Vue.jsのTypeScriptを簡単に導入したくてOptionsAPIを導入してみた!
今までのVue.jsの書き方に export default Vue.extend({})とするだけで簡単だったけど何故かエラーを吐く

Property 'hoge' does not exist on type 'CombinedVueInstance<Vue …省略

また、Vuexを使っている場合はmapGettersmapActionsなどで呼び出した関数のエラーが消せない。

結論: optionsの型を明示的に指定しようぜ!!

この形を基本形にして使いたい所の型を指定するだけ!!

<script lang="ts">
import Vue from 'vue'
import { ThisTypedComponentOptionsWithRecordProps } from 'vue/types/options'

interface Data {}
interface Methods {}
interface Computed {}
interface Props {}

const options:  ThisTypedComponentOptionsWithRecordProps<
  Vue,
  Data,
  Methods,
  Computed,
  Props
> = {
  data () {},
  computed () {},
  methods: {},
}

export default Vue.extend(options)
</script>

dataの型指定

特に何も考えずに指定するだけです。

<script lang="ts">
import Vue from 'vue'
import { ThisTypedComponentOptionsWithRecordProps } from 'vue/types/options'

interface Data {
  reutrn {
    form: {
      name: string|null;
      age: number|null;
      email: string|null;
    }
  }
}
interface Methods {}
interface Computed {}
interface Props {}

const options:  ThisTypedComponentOptionsWithRecordProps<
  Vue,
  Data,
  Methods,
  Computed,
  Props
> = {
  data () {
    form: {
      name: null,
      age: null,
      email: null
    }
  },
  computed () {},
  methods: {},
}

export default Vue.extend(options)
</script>

computedの型指定

今回はisLogin: boolean;のように型指定してみました。
関数で指定する場合はisLogin: () => boolean;みたいに指定できます!
もちろんVuexのmapGettersの関数の型も指定できるので便利です。

<script lang="ts">
import Vue from 'vue'
import { mapGetters } from 'vuex'
import { ThisTypedComponentOptionsWithRecordProps } from 'vue/types/options'
import { UserTypes } form '@/types/user'

interface Data {}
interface Methods {}
interface Computed {
  isLogin: boolean;
  loginUser: UserTypes;
  loginUserEmail: string;
}
interface Props {}

const options:  ThisTypedComponentOptionsWithRecordProps<
  Vue,
  Data,
  Methods,
  Computed,
  Props
> = {
  data () {},
  computed () {
    ...mapGetters(['isLogin'])
    ...mapGetters('modules/user', ['loginUser']),
    loginUserEmail () {
       return this.loginUser.email
    }
  },
  methods: {},
}

export default Vue.extend(options)
</script>

methodsの型指定

もう慣れてきたと思うのでテキトーに書きました。
また、返り値の無い関数ならvoid指定してあげるだけでOKです。

<script lang="ts">
import Vue from 'vue'
import { ThisTypedComponentOptionsWithRecordProps } from 'vue/types/options'
import { UserTypes } form '@/types/user'

interface Data {}
interface Methods {
  getLoginUser: () => Promise<UserTypes>;
  createUser: (user: UserTypes) => Promise<boolean>;
  isAdule: (age: number) => boolean;
}
interface Computed {}
interface Props {}

const options:  ThisTypedComponentOptionsWithRecordProps<
  Vue,
  Data,
  Methods,
  Computed,
  Props
> = {
  data () {},
  computed () {},
  methods: {
    ...mapActions(['getLoginUser', 'createUser'])
    isAdule (age) {
      return age >= 20
    }
  },
}

export default Vue.extend(options)
</script>

propsの型指定

ちょっと割愛します。
もし知りたければ東京都のCOVID19対策サイトのOSSのソースコードが上がっているので参考にしてみてください!

参考

tokyo-metropolitan-gov/covid19 - GitHub

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1