Edited at

Vue + TypeScriptでpropsのObjectやArrayに型をつける


Vue + TypeScriptでのpropsの推論

Vue 2.5でTypeScriptのサポートが強化されました。

その1つがpropsの推論で、propsにStringNumberなどと指定すると、それらの値をstring型、number型として利用できます。しかしArrayObjectは、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にはやはりtypeinterfaceを使って指定したいです。


ArrayとObjectにも型の指定を

Vueの型定義を読んでいると、型キャストを利用してArrayObjectにも型を指定できることを発見しました。方法は簡単で、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に余分な動作が入るなどといったことはありません。(個人的に重要なポイント)


さいごに

いつのまにか公式で用意してくれていたとは……