はじめに
Composition API を Typescript で使う際にハマったことの備忘録です。
随時更新していく予定。
Vue3 の環境構築はこちらから。vue-cli からかんたんに Vue3 環境を作成できます。
Version
Vue: 3.0.0
@vue/cli: 4.5.0
Typescript: 3.9.3
Tips
1. Recursive Type References
Composition API RFC のコードをそのまま Typescript で実行すると、以下のエラーが表示されます。
state
の定義中に、 自分自身(state
)を使用しているためです。
(Typescript のバージョンによっては発生しないらしいです)
'state' implicitly has type 'any' because it does not have a type
annotation and is referenced directly or indirectly in its own initializer.
setup() {
const state = reactive({
count: 0,
double: computed(() => state.count * 2)
});
return { state };
}
// use interface
interface Counter {
count: number;
double: number;
}
setup() {
const state: Counter = reactive({
count: 0,
double: computed(() => state.count * 2)
});
return { state };
}
// use ref
setup() {
const count = ref(0);
const double = computed(() => count.value * 2);
function increment() {
count.value++;
}
return {
count,
double,
increment
};
}
2. props
で型推論が効くようにする
そのままだと props
にほとんど補完が効かないため、 props
に ComponentObjectPropsOptions
を付与します。
こうすることで、 props
に指定した prop
に対し、 default
, required
といった property が補完されます。
import { defineComponent, ComponentObjectPropsOptions } from "vue";
interface CustomProps {
msg: string;
}
export default defineComponent({
name: "Home",
props: {
msg: {
required: true,
type: String,
default: "",
},
} as ComponentObjectPropsOptions<CustomProps>,
});
以下の図で、 required
が推論されているのが分かります。
また、defineComponent
の generics に任意の Type を与えることで、 prop
の型を縛ることができます。
上記のコードでは、 CustomProps.msg
の型が string
のため、 props.msg.type
に String
以外を指定するとエラーになります。
※ defineComponent<CustomProps>
でもできそうですが、うまくいきませんでした...
うまい方法を知っている方がいらっしゃったらご教示いただけると嬉しいです。