@@ -371,6 +371,17 @@ const foo = inject('foo') as string
371371
372372## テンプレート参照の型付け {#typing-template-refs}
373373
374+ Vue 3.5 と ` @vue/language-tools ` 2.1(IDE の言語サービスと ` vue-tsc ` の両方をサポート)では、SFC の ` useTemplateRef() ` で作成された ` ref ` の型は、` ref ` 属性が使用されている要素またはコンポーネントに基づいて、静的な ` ref ` の型を * 自動的に推論* できます。
375+
376+ 自動推論が不可能な場合でも、` generic ` 引数を使用してテンプレート参照を明示的な型にキャストすることができます:
377+
378+ ``` ts
379+ const el = useTemplateRef <HTMLInputElement >(null )
380+ ```
381+
382+ <details >
383+ <summary >3.5 以前の使用方法</summary >
384+
374385テンプレート参照は、明示的な型引数と初期値 ` null ` を指定して作成されます:
375386
376387``` vue
@@ -389,50 +400,45 @@ onMounted(() => {
389400</template>
390401```
391402
403+ </details >
404+
392405適切な DOM インターフェースを取得するには、[ MDN] ( https://developer.mozilla.org/ja/docs/Web/HTML/Element/input#技術的概要 ) のようなページを確認してください。
393406
394407厳密な型安全性のために、` el.value ` にアクセスする際には、オプショナルチェーンもしくは型ガードをする必要があります。なぜなら、コンポーネントがマウントされるまでは ref の初期値は ` null ` であり、参照されていた要素が ` v-if ` によってアンマウントされた場合にも ` null ` にセットされる可能性があるからです。
395408
396409## コンポーネントのテンプレート参照の型付け {#typing-component-template-refs}
397410
398- 時に、子コンポーネントのパブリックメソッドを呼ぶために、子コンポーネントのテンプレート参照に型づけする必要があるかもしれません。例えば、モーダルを開くメソッドを持つ ` MyModal ` という子コンポーネントがあるとします:
399-
400- ``` vue
401- <!-- MyModal.vue -->
402- <script setup lang="ts">
403- import { ref } from 'vue'
404-
405- const isContentShown = ref(false)
406- const open = () => (isContentShown.value = true)
411+ Vue 3.5 と ` @vue/language-tools ` 2.1(IDE の言語サービスと ` vue-tsc ` の両方をサポート)では、SFC の ` useTemplateRef() ` で作成された ` ref ` の型は、` ref ` 属性が使用されている要素またはコンポーネントに基づいて、静的な ` ref ` の型を * 自動的に推論* できます。
407412
408- defineExpose({
409- open
410- })
411- </script>
412- ```
413+ 自動推論が不可能な場合(例えば、SFC 以外の使用や動的コンポーネントの場合)でも、` generic ` 引数を使用してテンプレート参照を明示的な型にキャストすることができます。
413414
414- ` MyModal ` のインスタンスの型を得るために 、まず ` typeof ` によって型を取得し、次に TypeScript の組み込みユーティリティーの ` InstanceType ` を使って型を抽出する必要があります:
415+ インポートされたコンポーネントのインスタンスの型を得るために 、まず ` typeof ` によって型を取得し、次に TypeScript の組み込みユーティリティーの ` InstanceType ` を使って型を抽出する必要があります:
415416
416417``` vue{5}
417418<!-- App.vue -->
418419<script setup lang="ts">
419- import MyModal from './MyModal.vue'
420+ import { useTemplateRef } from 'vue'
421+ import Foo from './Foo.vue'
422+ import Bar from './Bar.vue'
420423
421- const modal = ref<InstanceType<typeof MyModal> | null>(null)
424+ type FooType = InstanceType<typeof Foo>
425+ type BarType = InstanceType<typeof Bar>
422426
423- const openModal = () => {
424- modal.value?.open()
425- }
427+ const compRef = useTemplateRef<FooType | BarType>('comp')
426428</script>
429+
430+ <template>
431+ <component :is="Math.random() > 0.5 ? Foo : Bar" ref="comp" />
432+ </template>
427433```
428434
429435コンポーネントの正確な型がわからない場合や重要でない場合は、代わりに ` ComponentPublicInstance ` を使用できます。この場合、` $el ` のようなすべてのコンポーネントで共有されているプロパティのみが含まれます:
430436
431437``` ts
432- import { ref } from ' vue'
438+ import { useTemplateRef } from ' vue'
433439import type { ComponentPublicInstance } from ' vue'
434440
435- const child = ref <ComponentPublicInstance | null >(null )
441+ const child = useTemplateRef <ComponentPublicInstance | null >(null )
436442```
437443
438444参照されるコンポーネントが[ ジェネリックコンポーネント] ( /guide/typescript/overview.html#generic-components ) の場合、例えば ` MyGenericModal ` の場合:
@@ -457,15 +463,16 @@ defineExpose({
457463``` vue
458464<!-- App.vue -->
459465<script setup lang="ts">
466+ import { useTemplateRef } from 'vue'
460467import MyGenericModal from './MyGenericModal.vue'
468+ import type { ComponentExposed } from 'vue-component-type-helpers'
461469
462- import type { ComponentExposed } from 'vue-component-type-helpers';
463-
464- const modal = ref<ComponentExposed<typeof MyModal> | null>(null)
470+ const modal = useTemplateRef<ComponentExposed<typeof MyModal>>(null)
465471
466472const openModal = () => {
467473 modal.value?.open('newValue')
468474}
469475</script>
470476```
471477
478+ なお、` @vue/language-tools ` 2.1 以降では、静的テンプレート参照の型は自動的に推論されるので、上記はエッジケースでのみ必要となります。
0 commit comments