🔰

Vue3のdefineModelで、オブジェクト値を双方向バインディングした時に起きた型エラーを解消する(TypeScript)

2024/07/09に公開

🐞 エラー概要

親コンポーネントでオブジェクト値を渡す

<script setup lang='ts'>
const modelValue = ref({
  name: '',
  email: '',
})
</script>

<template>
  <ChildComponant v-model="modelValue" />
</template>

子コンポーネントで受け取ってオブジェクトのプロパティにアクセスしようとするとエラーになる

<script setup lang='ts'>
const modelValue = defineModel()
</script>

<template>
  <div>
    {{ modelValue.name }} // 型エラー
  </div>
</template>

エラー文

💡 解消方法

  1. defineModelの型引数を指定する
type ModelValue = {
  name: string
  email: string
}
const modelValue = defineModel<ModelValue>()
  1. defineModelにrequired: trueオプションを追加する
const modelValue = defineModel<ModelValue>({ required: true })

1. defineModelの型引数を指定する

defineModelの型引数を指定してあげることで、modelValueのvalueプロパティの型がunknownからModelValue | undefinedに変わったことを確認

しかし、さらにnameプロパティにアクセスしようとするとundefinedの可能性があるとしてエラーが出てしまう…

2. defineModelにrequired: trueオプションを追加する

今回は親コンポーネントからnameプロパティとemailプロパティの初期値として空文字を渡しているので、undefinedになることはないということで、defineModelにrequired: trueのオプションを渡すと、modelValueの型からundefinedがなくなり、無事エラーが出なくなった

👀参考サイト

  • Vue公式

📝今回の学び

  • defineModelが型引数を受け取れることを初めて知った(実務でもconst model = defineModel()のように書くことはよくあるが、型引数を指定することがなかった)

Discussion