🎃

Vue+Typescriptで$refsで参照する際に型を付ける方法

2023/05/10に公開

こう書いていませんか?

例えばこんなコンポーネントがある場合。

Foo.vue
<template>
  <div v-show="isShow">test</div>
</template>

<script lang="ts">
import Vue from "vue"

export default Vue.extend({
  data() {
    return {
      isShow: false
    }
  },
  methods: {
    show() {
      this.isShow = true
    },
    hide() {
      this.isShow = false
    }
  }
})
</script>

上記を使用するコンポーネントで、refを使ってmethodsなどを参照したい場合、最初anyを使っていました。

Bar.vue
<template>
  <div>
    <foo ref="foo" />
    <button @click="showFoo">表示する</button>
  </div>
</template>

<script lang="ts">
import Vue from "vue"
import Foo from "./Foo.vue"

export default Vue.extend({
  components: {
    Foo,
  },
  methods: {
    showFoo() {
      ;(this.$refs as any).foo.show()
    },
  }
})
</script>

結論

anyは使わずに型付けするには、以下のような感じでas unknown as FooRefみたいに書く。

Foo.vue
<template>
  <div v-show="isShow">test</div>
</template>

<script lang="ts">
import Vue from "vue"

export type FooRef = {
  show(): void
  hide(): void
}

export default Vue.extend({
  data() {
    return {
      isShow: false
    }
  },
  methods: {
    show() {
      this.isShow = true
    },
    hide() {
      this.isShow = false
    }
  }
})
</script>
Bar.vue
<template>
  <div>
    <foo ref="foo" />
    <button @click="showFoo">表示する</button>
  </div>
</template>

<script lang="ts">
import Vue from "vue"
import Foo, { FooRef } from "./Foo.vue"

export default Vue.extend({
  components: {
    Foo,
  },
  methods: {
    showFoo() {
      ;(this.$refs.foo as unknown as FooRef).show()
    },
  }
})
</script>

型定義は@typesに置いても良いかもしれませんね。
以上です。

Discussion