Skip to content

Incorrectly inferred any type when using useTemplateRef #253

@DesselBane

Description

@DesselBane

Versions

- "eslint-plugin-vue": "10.6.2"
- "vue-eslint-parser": "10.2.0"
- "@types/node": "24.10.4"
- "@eslint/js": "9.39.2"
- "@vue/eslint-config-typescript": "14.6.0"
- "eslint": "9.39.2"
- "eslint-import-resolver-typescript": "4.4.4"
- "jiti": "2.6.1"
- "prettier": "3.8.1"
- "typescript": "5.9.3"
- "typescript-eslint": "8.50.0"

Configuration

import { defineConfig } from 'eslint/config'
import eslint from '@eslint/js'
import {
  configureVueProject,
  defineConfigWithVueTs,
  vueTsConfigs,
} from '@vue/eslint-config-typescript'
import pluginVue from 'eslint-plugin-vue'

function createEslintConfig() {
  const projectServiceConfig = {
    languageOptions: {
      parserOptions: {
        projectService: true,
        tsconfigRootDir: import.meta.dirname,
      },
    },
  }

  configureVueProject({
    tsSyntaxInTemplates: true,
    rootDir: import.meta.dirname,
  })

  return defineConfig(
    eslint.configs.recommended,
    // @ts-expect-error - This is a valid config, but the types are currently wrong
    ...defineConfigWithVueTs(
      projectServiceConfig,
      pluginVue.configs['flat/recommended'],
      vueTsConfigs.stylisticTypeChecked,
      vueTsConfigs.strictTypeChecked,
    ),
  )
}

export default createEslintConfig()

Error site

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

const someOtherName = useTemplateRef('someElement')

const doubleHeight = computed(() => {
  const height = someOtherName.value?.clientHeight ?? 0
  return height + height
})

</script>
<template>
  <div ref="someElement">
    Hi there! My double height is {{ doubleHeight }}px.
  </div>
</template>

What did you expect to happen?

That the height variable inside the doubleHeight computed is of type number

What actually happened?

The height variable inside the doubleHeight computed is detected as type any which triggers an error from the @typescript-eslint/restrict-plus-operands (though any rule with type information might be a problem here)

Link to Minimal Reproducible Example

https://github.com/DesselBane/repro-vue-eslint-any

Additional comments

Possible workaround is to explicitly specify the type of the template ref like this

<script setup lang="ts">
import { computed, useTemplateRef, type TemplateRef } from 'vue'

const someOtherName: TemplateRef<HTMLDivElement> = useTemplateRef('someElement')

const doubleHeight = computed(() => {
  const height = someOtherName.value?.clientHeight ?? 0
  return height + height
})

</script>
<template>
  <div ref="someElement">
    Hi there! My double height is {{ doubleHeight }}px.
  </div>
</template>

Also reported to vue-eslint-parser (vuejs/vue-eslint-parser#285) as I think the issue is there but in case its not I'll report it here as well.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions