0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Vue.js の v-slot でスロットのスコープ変数をなんとか推論させる

0
Posted at

Vue.js の v-slot でスロットのスコープ変数をなんとか推論させる

最近の Vetur では <template> 配下でも変数の型を確認できるようになってきましたが
スロットのスコープ変数については any になりがちです。

child
<template>
  <div>
    child
    <slot :id="id" :namae="namae" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      id: 1,
      namae: 'Taro',
    };
  },
};
</script>
parent
<template>
  <div>
    parent
    <child>
      <template v-slot="slotProps">
        child 使用
        {{ slotProps }}
      </template>
    </child>
  </div>
</template>

<script>
import Child from './child.vue';

export default {
  components: {
    Child,
  },
};
</script>

child.jpg

child 自身では template 中の変数の型を確認可能だが・・・

parent.jpg

parent 側で使用した際の変数では any

browser.jpg

実際の画面表示では slotProps の中身は id, namaechild にて指定した通り

これについて parent 側にて id などの型の確認ができないかなどをやってみます。

スロット側で変数を明確にする関数を定義して export

スロットを持つ child 側にて「何もしない」が型を明示する関数を用意してみます。

child-vs

<script>
/**
 * @typedef {Object<string, any>} SlotProps
 * @property {number} id
 * @property {string} namae
 */
/**
 * @param {SlotProps} slotProps
 * @return {SlotProps}
 */
export const vs = slotProps => slotProps;

export default {
  data() {
    return {
      id: 1,
      namae: 'Taro',
    };
  },
};
</script>

定義された関数 vs は引数に渡された値をそのまま返すだけのアロー関数です。
@typedef により型定義した SlotProps はそれぞれ child での <slot> に渡している要素と同一の構造のオブジェクトの定義となります。

使用側でスロット側で定義した変数用関数を適用

上記の vsparent にて適用すると・・・

parent-vs
<template>
  <div>
    parent
    <child>
      <template v-slot="slotProps">
        child 使用
        {{ vs(slotProps) }}
        {{ vs(slotProps).id }}
        {{ vs(slotProps).namae }}
      </template>
    </child>
  </div>
</template>

<script>
import Child, { vs } from './child.vue';

export default {
  components: {
    Child,
  },
  methods: {
    vs,
  },
};
</script>

child.vue より vsimport して parentmethods に追加しています。
これをエディタ上で確認してみると以下のようになります。

slotProps.jpg

slotProps は相変わらず any

vs.jpg

child より import した vs は定義した通りで推論されます。

id-inferred.jpg

vs(slotProps) の結果より生やした idJSDoc で定義した通り number で確認できました。
(残念ながら vs(slotProps) の結果から .id などは候補としては取得できませんでした・・・)

not-exist.jpg

JSDoc にて定義していない abababab を指定してみたところ
SlotProps 型に存在しない旨のメッセージが表示され、想定しないプロパティへのアクセスであることも確認できました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?