2020/07/28 時点の Vue 2.x + TypeScript について言える確かなこと
できる・できないをまとめておく。
なお、 Class Component の記法は Vue 3 の仕様から Drop されたので、そこについて言及する場合はその旨を明確にする。
this の型について
基本的に全て有効化できる。 Vue 2.5 より this の型が正しく使えるようになっている。しかし、いくつかの条件がある
tsconfig.json において、 noImplicitThis が true である必要がある
既存プロジェクトからの移行でない限りは strict: true であるはずなので、問題ない
逆に、既存プロジェクトの TS 化については、 noImplicitThis を false として Vue Template 以外の純粋な JavaScript 部分から段階的に移行できる。
computed などについて、戻り値を明示的に指定する必要がある
これは Vetur / TypeScript によって実現している型の推論において、推論の循環参照を防ぐため
詳しくはこちら
これをやっていないがために通らずに、うまくつかずに any になると言っている人が一定数いる気がしている
props の型(受け取る側)について
props: { item: Object as () => Item } あるいは props: { item Object as PropType<Item> }で実現できる
これもあまり知られていない可能性があるが、 Object に対して as を書ける記法で実現する
コンポーネント呼び出し側について
<ItemView /> みたいに item の prop が required なのに忘れているケース
具体的には正しい prop が渡されていない場合 tsc レイヤーでエラーになる。Vetur ではなく、純粋なTSとして。
Vue + TSX で書く場合は基本的に vue-tsx-support に頼ることになるので現実的には TSX では可能という状態
Vue Template については後述
HTML 部分の型について
TSX では何も問題なくすべてが動作する。
Vue Template では、 Vetur の Experimental なオプションを有効化することで実現できる。開発者の環境依存。
Vuex について
次期バージョンである Vuex 4 にて Store<T> の Tがハードコーディングされる問題が解消されることが確定している
しかし、 Vue 2.x + Vuex 3.x の現状は、 this から store へアクセスするときは、基本的に直接型をつけることはできない
this.$store.dispatchのようなケース
vue-property-decorator を使う場合は、コンポーネント内で $store の型を上書きすることで実現可能
Class 記法で Vue を使っている人はこれがモチベーションであることが多い印象
this.$typedstore を用意するなどの苦し紛れでは可能
この都合が Vue 2.x において Vuex 離れに拍車をかけている
@potato4d は Nuxt.js の inject を利用しているので Vuex を使っていない
これは普通に問題
this.$xxx の型について
vue/types/vue の拡張によって実現できる。問題なし。外部ライブラリもここを拡張する。
ただ vue/types/vue を激しく拡張することが前提になるのは weak point かもしれない。
結論
基本的な部分は大体できるので正しく伝わってほしい。
余談
Vue で TSX 使ってると tsserver がめっちゃ死ぬ。