Vue 2 + Composition API の型チェックについて調べる
このスクラップの内容はめちゃ古いです、いまは Volar とか使ってください
なにか怪しいところがあったら教えてください
前提
- Nuxt 環境だけど Vue 2 一般に当てはまると思う
- Vue 3 にもそれなりに当てはまりそう
- もちろんエディタでも CI でもチェックしたい
props の型は PropType で定義できる。
props: {
book: {
type: Object as PropType<Book>,
required: true,
}
},
setup(props) {
// props.book is typed as Book
}
ただし、import が必要な型で PropType を使うと Vetur がコンポーネントの呼び出し側で cannot find name
エラーを吐いてしまう問題がある(vuejs/vetur#2457)。
そのため、import が必要な型を含む場合は、今のところ PropType を使わないワークアラウンドを用いたほうがよさそう。
props: {
book: {
type: Object as () => Book,
required: true,
}
},
setup(props) {
// props.book is typed as Book
}
Function props の引数や返り値の型に import が必要なときもやはり PropType
は使えない。この場合、Function
をそのままキャストできないので、以下のように unknown
を噛ませることになる。
Before:
props: {
callback: {
type: PropType<(book: Book) => void>,
required: true,
}
},
setup(props) {
// props.callback is typed as `(book: Book) => void`
}
After:
props: {
callback: {
type: (Function as unknown) as () => (book: Book) => void,
required: true,
}
},
setup(props) {
// props.callback is typed as `(book: Book) => void`
}
呼び出し側の props 型チェックをしっかり行う方法は今のところなさそう。
Vetur を使うと以下のことはできる。
- required な props を渡しているかチェック
- string や number などのプリミティブな props の型チェック
PropType で定義した型への対応の議論は vuejs/vetur#2344 で行われている。
Vetur Terminal Interface という実験的なプロジェクトがあり、これを使うと Vetur でできるチェックを CI で行うことができる。required props を strict にできるだけでも結構助かる。
ただし結構時間がかかって、手元の eslint check が 25s で終わるプロジェクトだとだいたい 300s かかった。
Vetur に型チェックを実装してくれた ktsn さんの記事によるとかなりの腕力で実装されているみたいで(すごい)、仕方ない部分ではあると思う。
WebStorm 使いに聞いたところ、props の検査は今のところできないらしい。僕は使ってないからわからないけど。
テンプレート内での変数型チェックは props の型情報と setup
関数の戻り値の型情報をいい感じに合成しているっぽく、戻り値を返さない setup
関数を定義すると props の型まで壊れて never
になった。setup
関数の戻り値がない場合は空オブジェクトを返すか、そもそも setup
関数が不要な場合は定義しないほうがよい。
例えば以下のように定義したコンポーネントで、テンプレートから book
を読むと never
型になる。
props: {
book: {
type: Object as () => Book,
required: true,
}
},
setup() {}