Skip to content

Template ref type inference doesn't work when using defineComponent (but does work in <script setup>) #5073

Closed as not planned
@catrope

Description

@catrope

Vue - Official extension or vue-tsc version

2.1.10

VSCode version

N/A

Vue version

3.5.13

TypeScript version

5.7.2

System Info

System:
    OS: Linux 6.8 Ubuntu 24.04.1 LTS 24.04.1 LTS (Noble Numbat)
    CPU: (12) x64 12th Gen Intel(R) Core(TM) i7-1265U
    Memory: 32.74 GB / 46.72 GB
    Container: Yes
    Shell: 5.2.21 - /bin/bash
  Binaries:
    Node: 18.20.4 - ~/.nvm/versions/node/v18.20.4/bin/node
    npm: 10.7.0 - ~/.nvm/versions/node/v18.20.4/bin/npm
    pnpm: 9.5.0 - ~/.nvm/versions/node/v18.20.4/bin/pnpm
  Browsers:
    Chrome: 131.0.6778.139
    Chromium: 128.0.6613.84

package.json dependencies

No response

Steps to reproduce

Bind a template ref to a native HTML element in a component that uses <script setup>:

<template>
    <div>
        <p>{{ msg }}</p>
        <input ref="input" v-model="msg">
        <button @click="focusInput">Focus</button>
    </div>
</template>

<script setup lang="ts">
import { useTemplateRef } from 'vue';

const input = useTemplateRef( 'input' );
function focusInput() {
    input.value?.focus();
}
</script>

Then write the same code, but using defineComponent:

<template>
    <div>
        <p>{{ msg }}</p>
        <input ref="input" v-model="msg">
        <button @click="focusInput">Focus</button>
    </div>
</template>

<script lang="ts">
import { defineComponent, useTemplateRef } from 'vue';

export default defineComponent( {
    setup() {
        const input = useTemplateRef( 'input' );
        function focusInput() {
            input.value?.focus();
        }
        return { focusInput };
    }
} );
</script>

What is expected?

In both cases, vue-tsc should automatically infer the type of the input template ref as HTMLInputElement, and so it accepts input.value?.focus() because HTMLInputElement has a focus method.

What is actually happening?

In the <script setup> case, inference works correctly. But in the defineComponent case, vue-tsc does not infer the type of the input template ref, resulting in a TypeScript error for input.value?.focus(), because the type of input.value is unknown.

Link to minimal reproduction

No response

Any additional comments?

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions