'Vue 3 / Typescript: "Cannot find name" in template variable
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 |

