Dealing with route parameter typing issues in TypeScript when using unplugin-vue-router

Currently, I am delving into Vue 3 with the Composition API and TypeScript. In one of the tutorials I am following, there is a recommendation to employ unplugin-vue-router for automatic generation of routes based on certain file naming/path conventions. Although the plugin functions properly, I am encountering issues with TypeScript when it comes to route parameters. For instance, consider this simple Vue page:

<script setup lang="ts">
import { useRoute } from 'vue-router'
const route = useRoute()
</script>

<template>
  <div>
    <h1>Page slug: {{ route.params?.slug }}</h1>
  </div>
</template>

The problem arises when TypeScript flags `slug` and displays a warning stating that "Property 'slug' does not exist on type 'Record<never, never> | { catchAll: string; } | { slug: string; } | { id: string; }'."

https://i.sstatic.net/oJf4p53A.png

After conducting some research online, I stumbled upon an identical issue on the unplug-vue-router Github repository. However, the suggestion to "use type narrowing" seems vague and has not resolved the situation in my case.

How can I resolve this TypeScript error occurring while using route parameters and unplugin-vue-router?

Answer №1

If you want to specify a type for useRoute, you can do so in this way:

const route = useRoute<'ProductDetails'>()

The type 'ProductDetails' is defined within the RouteNamedMap that is provided by unplugin-vue-router:

'ProductDetails': RouteRecordInfo<'ProductDetails', '/products/:id', { id: ParamValue<true> }, { id: ParamValue<false> }>,

But please note that using this method may result in a TypeScript error stating: Type '"ProductDetails"' does not satisfy the constraint 'keyof RouteNamedMap'.

Referencing the documentation provides more insights:

// these are all valid
let userWithId = useRoute() as RouteLocationNormalizedLoaded<'/users/[id]'>
userWithId = useRoute<'/users/[id]'>()
// 👇 this one is the easiest to write because it autocompletes
userWithId = useRoute('/users/[id]')

userWithId.params

So there might be an option that suits your needs better.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Displaying a List in VueHere are some ways

Struggling to iterate through a list of cart items in vue and retrieve the index for each item. Here's what I've attempted: <ul class="crt-Push_Items"> <li class="crt-Push_Item" v-for="(lineItem, index) in li ...

Triggering a new window on button click with Vue and Nuxt

Having an issue with a button click event in Vue that opens a PDF using window.open(). It's working well on all browsers except for Safari on MAC. Any ideas what could be causing this? Should I pass $event to the method? <div class="button-do ...

Creating a smooth entrance effect in VueJS using CSS transitions is a breeze

Even though it seems simple, I am struggling to get it to work properly. My goal is to have the existing elements in my list shift to make room for a new element added, and then have the new element appear with a smooth fade transition. I have tried to im ...

The 'palette' property is not found on the Type 'Theme' within the MUI Property

Having some trouble with MUI and TypeScript. I keep encountering this error message: Property 'palette' does not exist on type 'Theme'.ts(2339) Check out the code snippet below: const StyledTextField = styled(TextField)(({ theme }) = ...

Top 5 Benefits of Utilizing Props over Directly Accessing Parent Data in Vue

When working with VueJS, I've noticed different approaches to accessing parent properties from a component. For example, let's say I need to utilize the parent property items in my component. Option One In this method, the component has a props ...

A function injected into a constructor of a class causes an undefined error

As I delve into learning about utilizing typescript for constructing API's, I have encountered a couple of challenges at the moment. Initially, I have developed a fairly straightforward PostController Class that has the ability to accept a use-case wh ...

Vue.js V-for not rendering any content

I am currently working on populating an array with objects retrieved from an API. The objects are being fetched successfully, but I am facing issues when trying to display them using v-for in the array. Below are my data variables: data() { return { ...

TS and React: Comparing View['props'] to React's ComponentProps<typeof View>

When dealing with an existing React component (referred to here as View), it appears that there are two methods to determine the type of props if it's not exported. Could someone explain the difference between these two approaches? Using lookup typ ...

Are there any disadvantages to keeping the selector of routed components in place?

The instructions in the Angular routing documentation - Add heroes functionality mention making some adjustments: Several changes need to be made: -Remove the selector (routed components do not need them). -Remove the <h1>. Is it beneficial to kee ...

filter failing to provide output

Issue with fetching partnername from the filter function, always returning undefined. administrationList = [ { "runid": 6, "partnerid": 2, "partnername": "test admin2", }, { "runid& ...

How can I generate a distinct reference for a nested v-for loop?

I have a structured array of objects that looks like this: itemList: [{ itemName: "Item One" },{ itemName: "Item Two", children: [{ itemName: "Child One" },{ itemName: "Child Two" }] },{ item ...

Using callback functions with server.listen in Typescript and JavaScript

I'm puzzled why the following codes are not functioning in TypeScript. (They used to work perfectly fine in my previous JavaScript code!) http.createServer(app).listen(port, (err) => { # Do something }); However, this code works flawlessly (wi ...

Retrieve data upon component mounting and deactivate the query in React-query

When navigating to a search result page, query parameters are passed to useQuery. I want the data to be fetched only when the user clicks the "Search" button after changing the search prompt. I attempted to use enabled: false and call refetch() on button ...

Testing Angular Dependency Injection - @Injectable() proves unsuccessful, whereas @Inject() functions correctly

Issue with Dependency Injection in Angular 5 and Webpacker Integration Upon integrating webpacker with Angular 5 into an existing Rails application, everything seemed to be functioning properly except for a peculiar issue with Dependency Injection during ...

transmitting information from the state to actions in Vuex

I am trying to pass latitude and longitude coordinates from the state to an action in order to retrieve the city name based on the coordinates. However, I have noticed that using state.lat and state.lng directly in the axios.get URL does not work. What a ...

Uploading Images in VueJs using Laravel

Hey everyone, I'm currently facing a challenge with uploading images from VueJs to a Laravel endpoint. So far, the only method I have found is sending the base64 of the image through the request. The Vue side seems well set up for this task. However, ...

Bidirectional communication linking an Angular 2 component and service utilizing the power of Observables

I'm having difficulties establishing a simple connection between an Angular 2 component and service using Observable. I've been trying to achieve this, but I can't seem to get it right. Here's the scenario: My component HeroViewerCompo ...

Tips for connecting an input tag within a popover to a Vue Model

I've got an input nested inside a popover content as shown below: JSFiddle Link HTML code snippet: <div id="vue-app"> <div class="btn btn-primary" data-toggle="popover" data-placement="bottom" title="Hello World!" data-html="true" data ...

Tips for adjusting the font weight and size of the label within a Quasar Tab

I've been working on my project using Q-Tab, and I've been trying to adjust the font size and weight of the tab labels without success. I've experimented with the typography options in Quasar, but nothing seems to work. <q-tabs v-model= ...

Is there a way to access a specific argument in yargs using typescript?

The idea behind using yargs is quite appealing. const argv = yargs.options({ env: { alias: 'e', choices: ['dev', 'prod'] as const, demandOption: true, description: 'app environment&apos ...