Vue + TypeScriptでのpropsの推論
Vue 2.5でTypeScriptのサポートが強化されました。
その1つがpropsの推論で、propsにString
、Number
などと指定すると、それらの値をstring型、number型として利用できます。しかしArray
やObject
は、any[]型、any型になってしまいます。
// 適当なクラス
class Foo {}
Vue.extend({
props: {
str: String,
num: Number,
foo: Foo, // カスタムコンストラクタ
arr: Array,
obj: Object,
},
created() {
this.str // string型
this.num // number型
this.foo // Foo型
this.arr // any[]型 <- この2つを
this.obj // any型 <- 何とかしたい
},
}
Foo
のようなカスタムコンストラクタには対応していますが、Object
にはやはりtype
やinterface
を使って指定したいです。
ArrayとObjectにも型の指定を
Vueの型定義を読んでいると、型キャストを利用してArray
やObject
にも型を指定できることを発見しました。方法は簡単で、string[]型を利用したい部分にArray as () => string[]
を指定します。(下の例ではProp
を定義してそれを使っています)
【追記・修正】
Vueの型定義にPropTypeがありましたので、そちらに書き換えました。
import Vue, { PropType } from 'vue'
// 適当なインターフェース
interface Bar {}
Vue.extend({
props: {
arr: Array as PropType<string[]>,
obj: Object as PropType<Bar>,
fnc: Function as PropType<() => void>,
// 省略可能なプロパティを指定する時にも利用できる
optional: {
type: String as PropType<string | undefined>,
required: false,
},
},
created() {
this.arr // string[]型
this.obj // Bar型
this.fnc // (() => void)型
this.optional // (string | undefined)型
},
})
型のキャストしか行っていないので、実行時のJavaScriptに余分な動作が入るなどといったことはありません。(個人的に重要なポイント)
さいごに
いつのまにか公式で用意してくれていたとは……