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

## 問題提起

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

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

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

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

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

```vue
<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の型指定

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

```vue
<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の関数の型も指定できるので便利です。

```vue
<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です。

```vue
<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のソースコードが上がっているので参考にしてみてください！
↓

https://github.com/tokyo-metropolitan-gov/covid19/blob/development/components/MonitoringConsultationDeskReportChart.vue#L126

## 参考
[tokyo-metropolitan-gov/covid19 - GitHub](https://github.com/tokyo-metropolitan-gov/covid19/blob/development/components/MonitoringConsultationDeskReportChart.vue#L126)