Vue の単一ファイルコンポーネントを TypeScript で書く方法はいくつかある。僕はなるべく JS に近い書き方をしたくて、Vue.extend
を使っているのだが、時々下のような型エラーが発生する。
Property 'XXX' does not exist on type 'Vue'.
なお、ここで言う XXX
とは、SFC 内にある computed
の変数だったり methods
にある関数だったりする。このようなときに確認するべき場所を自分の備忘録も兼ねてまとめておく。
computed や methods の関数にアノテーションをつけているか
Vue.extend()
で型の推論を行っている場合、引数として書いたオブジェクトをもとに、そのオブジェクト内で使われる this
の推論が行われる。そのため、型推論に頼っていると、しばしば失敗して this
の型が正しく認識されなくなるのである。(雑な理解なので、詳しい方いたら教えてください)
対処法としては、computed
やmethods
に書いた関数には、しっかり下のようにアノテーションを書いてあげれば良い。これは Vue の TypeScript サポートに関するページにも記載があるが、ちょくちょくフォーラムでも同様の質問があり、案外見落としがち(自分もハマった)。
import Vue from 'vue';
export default Vue.extend({
data() {
return {
msg: 'Hello'
};
},
methods: {
// アノテーションをしっかり書く
greet(): string {
return this.msg + ' world';
// ~~~ ← 書かないとここがエラーになることがある
}
},
computed: {
// ここもアノテーションをしっかり書く
greeting(): string {
return this.greet() + '!';
// ~~~~~ ← 書かないとここがエラーになることがある
}
}
});
オプションなどをスペルミスしていないか
昨日ハマったのはこっち。例えば、下のようにpropsのオプションを書き間違えたとする。
export default Vue.extend({
props: {
imageUrl: {
type: String as PropType<string>,
require: true // ← 本当は require"d" !!!
}
},
});
この場合にも、冒頭に書いたエラーがthisに生えている変数や関数すべてに発生してしまう。同様に type
を tyep
にスペルミスしたときとかにも起こるので気をつけたい。
参考: Vue/Typescript 3.5.1 Error: 'property' does not exist on type 'Vue' - Get Help - Vue Forum
https://forum.vuejs.org/t/vue-typescript-3-5-1-error-property-does-not-exist-on-type-vue/65591
まとめ
エラーメッセージが直接的ではない分、原因の特定に時間を食いがちなので気をつけましょう😇