'Vue 3 / Typescript: "Cannot find name" in template variable

In Vue 3 / Typescript, I am getting the following error:

"Cannot find name", when referencing a data variable into the ... area.

How can I solve this?

Please see the attached screenshot.

enter image description here

Many thanks in advance.



Solution 1:[1]

I had a similar issue when I added lang="ts" to the vue file as I'm new to Vue 3 and Typescript. I resolved it by ensuring the following:

export default 

to

export default defineComponent({

in your .vue file.

Ensure you add the import.

import { defineComponent }

Your data should reside in the setup as well.

setup () {
  return {
    loader: false,
    error: false,
    firstTime: false

Solution 2:[2]

The Composition API helps greatly with this issue. There does not seem to be a clear path to deal with the problem in the Options API.

One way to deal with the issue in the Options API:

Create a MyComponent.d.ts file that corresponds to the component that you are working with and add the following in that file:

declare module '@vue/runtime-core' {
  interface ComponentCustomProperties {
    myTroublesomeVariable: boolean // change here
  }
}

Solution 3:[3]

I had same issue.

Couldn't find a solution after inspecting VSCode/TS and Volar.

Created tiny reproduction (wanted to post it in Discord):

<template>
  <input v-model="email" />
</template>

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

  const email = ref('')
</script>

After I saved this file as Test.vue the error in other files disappeared. Sorry, but I don't know why...

Solution 4:[4]

I don't know if you still have this bug, but, I also had this. I have fix it by fixing a silent TS bug. When I have fix this bug, everything was working again.

EDIT: I found the bug I had. I had put an enum in a *.d.ts file and I was using this enum in the file that gave me the same error as you. The problem is that an enum can't be in a *.d.ts file because it is not compiled in JS afterwards and you lose the enum's value. By fixing this bug, I didn't have the errors displayed anymore. What I mean by this is not that there is a simple solution to your problem, but that maybe like me, you have a silent bug that hides and causes these errors!

Solution 5:[5]

Use defineComponent instead of export default class ParentSupervise extends Vue. Write like this:

<template>
  <div class="hello">
    <h1>{{ book.title }}</h1>
  </div>
</template>

<script lang="ts">
import { reactive, ref, defineComponent } from "vue";

interface Book {
  title: string;
}
const HelloWorld = defineComponent({
  data() {
    return {
      boardFields: "??",
    };
  },
  setup() {
    let name = ref("?");
    const book = reactive({ title: "Vue 3 Guide" }) as Book;
    debugger;
    console.log("name :>> ", name);
    console.log("book :>> ", book);
    // ??? template
    return {
      book,
      name,
    };
  },
});
export default HelloWorld;
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss"></style>

Solution 6:[6]

I also encountered the same bug, the code inference error, that was caused by the code loop reference.

I create a route-array-contant in route.ts, such as the following:

import { RouteRecordRaw, createRouter, createWebHistory } from "vue-router";

import Layout from "../layout/index";

export const NaviHeaderRoutes: RouteRecordRaw[] = [
  {
    path: "/foo",
    name: "FOO",
    redirect: "/foo/index",
    component: Layout,
    children: [
      {
        path: "index",
        name: "foolIndex",
        component: () => import("../views/foo/index")
      }
    ]
  },
  {
    path: "/bar",
    name: "BAR",
    redirect: "/bar/index",
    component: Layout,
    children: [
      {
        path: "index",
        name: "barIndex",
        component: () => import("../views/bar/index")
      }
    ]
  }
];

const routes: RouteRecordRaw[] = [
  ...NaviHeaderRoutes
];

const router = createRouter({
  history: createWebHistory(),
  routes
});

export default router;

then I use NaviHeaderRoutes in the child component of Layout.vue

// layout.vue
<template>
  <NaviHeader></NaviHeader>
    <!-- error TS2304 cannot find name  in template variable -->
    <main :class="testClass">
      <RouterView />
    </main>
</template>
<sciprt lang="ts" setup>
const testClass = ref();
</script>
// naviheader
<template>
 <header>
 <!--error TS2304 cannot find name  in template variable-->
 <span>{{title}}</span>
 <span v-for="(hitem in NaviHeaderRoutes)" :key="hitem.name">
    <router-link :to="hitem.path">{{hitem.name}}</route-link>
 </span>
 <!--error TS2304 cannot find name  in template variable-->
 <div>{{username}}</div>
</header>
</template>
<script lang="ts" setup>
import {NaviHeaderRoutes} from '@/router'
const title = ref('')
const username = ref('')
</script>

Fix it is simple, try to set route's component lately

export const NaviHeaderRoutes: RouteRecordRaw[] = [
  {
    path: "/foo",
    name: "FOO",
    redirect: "/foo/index",
    // component: Layout,
// ....
]

const routes: RouteRecordRaw[] = [
  ...NaviHeaderRoutes.map((x) => {
    x.component = Layout;
    return x;
  })
];

Solution 7:[7]

You are missing setup within <script lang="ts"> so it should be:

<script setup lang="ts">

From the docs:

When using <script setup>, any top-level bindings (including variables, function declarations, and imports) declared inside are directly usable in the template (...)

https://v3.vuejs.org/api/sfc-script-setup.html#top-level-bindings-are-exposed-to-template

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 iknowmagic
Solution 3 Crow
Solution 4
Solution 5 Henry Ecker
Solution 6 Phillyx
Solution 7 joe.kovalski