Creating data types from the name of the route in vue-router route[x]

I am attempting to generate route names based on the routes defined in the Vue Router. My goal is to utilize a helper function called findRouteByName() to locate a specific route.

However, I encountered an issue when trying to define the parameters of the helper function with the actual route.name as types. The error message displayed was:

The type 'readonly [{ readonly path: "/"; readonly name: "Root"; readonly children: 
readonly []; }, { readonly path: "/somePath"; readonly name: "somePath1"; readonly component: 
"Blub"; readonly children: readonly []; }, { readonly path: "/somePath2"; readonly name: 
"somePath2"; readonly component: "Blub"; readonly children: ...' is 'readonly' and cannot be assigned 
to the mutable type 'RouteRecordRaw[]'.(4104)

Nevertheless, there is a workaround...

For instance: https://i.sstatic.net/2zOGa.png

The example illustrated in the image functions properly if I refrain from assigning the routes the type RouteRecordRaw[].

In doing so, I am able to achieve my objective and use the types as parameters in the function successfully.

However, it is imperative that I designate RouteRecordRaw[] as the type for the routes. Otherwise, an error will occur during router initialization. Therefore, it is necessary to work with RouteRecordRaw[].

I have set up everything on Stackblitz, hoping that someone might come up with an elegant solution for this dilemma.

Check out the Stackblitz Example

Answer №1

Consider using satisfies RouteRecordRaw[] in place of as const.

This way, you can achieve the same type deduction without triggering any warnings related to unnecessary readonly declarations.

Answer №2

Here's a method to ensure that all types are fulfilled while still benefiting from Intellisense for findRouteByName -

router/index.ts

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

type ForceMergeTypes<T, K> = T | (K & Record<never, never>);

type Paths = "/" | "somePath" | "somePath2";
type Names = "Root" | "somePath" | "somePath2";

type ExtendedRouteRecordBase = _RouteRecordBase & {
  path: ForceMergeTypes<Paths, RouteRecordRaw["path"]>;
  name?: ForceMergeTypes<Names, RouteRecordRaw["name"]>;
};

type RoutesRecord = ExtendedRouteRecordBase & RouteRecordRaw;

const routes: Array<RoutesRecord> = [
  {
    path: "/",
    name: "Root",
    component: null,
    children: [],
  },
  {
    path: "/somePath",
    name: "somePath1",
    component: null,
    children: [],
  },
  {
    path: "/somePath2",
    name: "somePath2",
    component: null,
    children: [],
  },
];

export function findRouteByName(name: (typeof routes)[number]["name"]) {
  return routes.find((route) => route.name === name);
}

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes,
});

findRouteByName("");

export default router;

By implementing this strategy, you can input any string for path & name and still receive Intellisense for the strings defined in types Path and Names. Let me know if I overlooked anything or if it doesn't align with your needs.

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

Note: While using this, you may not experience Intellisense in Stackblitz, but you will in your IDE like VSCode due to limitations of Stackblitz.

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

The unit test is not passing due to inconsistencies between the mock data generated in the constructors and the original mock data

Currently, I am delving into the world of unit testing and have created a test to work on. Here is what I have so far: const EXEPECTED: MergedFood = { id: '1', name: 'test mergedFood', ingredients: { '2': ...

Setting up a custom UI Kit and font package with Laravel 5.6 and Vue.js

I am currently facing some challenges while trying to integrate Now-UI-Kit into my Laravel 5.6 project with vue.js. For reference, the URL to access the Now-UI-Kit is: Prior to this, I was able to successfully install a plain UI Kit by following straight ...

Troubleshooting Image Upload Problem with Angular, Node.js, Express, and Multer

While trying to implement the functionality of uploading an image, I have been referencing various guides like how to upload image file and display using express nodejs and NodeJS Multer is not working. However, I am facing issues with getting the image to ...

Tips on pairing elements from a ngFor processed list with another list using ngIf

If we have a list such as the one shown below: elements = [ { id: 1, name: "one" }, { id: 3, name: "three" }, { id: 5, name: "five" }, { id: 6, name: "six" }, ]; lists = [ { id: 5, name: "five" }, { id: 9, ...

The Context API's `useContext` hook appears to be malfunctioning, persistently

My situation is as follows: export const LocationContext = createContext(null); export const LocationProvider = LocationContext.Provider; export const useLocationContext = () => useContext(LocationContext); Using the Provider: export const Search = () ...

What is the process for declaring global mixins and filters on a Vue class-based TypeScript component?

Recently, I've been working on incorporating a Vue 2 plugin file into my project. The plugin in question is called global-helpers.ts. Let me share with you how I have been using it: import clone from 'lodash/clone' class GlobalHelpers { ...

Dealing with the issue of dynamic template rendering in Vue.js with v-runtime-template

Currently working on an aspnet core project where I am utilizing Vuejs, vuetify, and v-runtime-template. Encountering issues with the stability of the CSS when binding a dynamic vuetify component (v-select) to the v-runtime template Combobox. Seeking guida ...

The Vuex store has been refreshed, but the DOM remains unchanged

I've scoured all the discussions on this topic and can't find a solution. My Vuex store is updating correctly, but the DOM isn't reflecting the changes. Here's a screenshot of the issue One of my getters, called returnAmazonCredential ...

Vuetify has encountered an error due to exceeding the maximum call stack size

I am currently utilizing Vuetify Dialog in my code snippet below <v-dialog max-width="390" persistent v-model="dialog"> <template v-slot:activator="{ on }"> <v-btn icon v-if="el.items_count == 0" v-on="on" > <v-icon> ...

The benefits of exporting a component from one module and using it in another module

After putting in long hours trying to figure this out on my own, I've finally decided to seek help from the community. Thank you in advance for any assistance! I have a Web Projects Module that utilizes a Webpage Component. Within the Webprojects Mod ...

Utilizing Vue's v-for directive to manipulate data through custom looping

When I loop through my data using v-for, I find myself unsure of how to display the data with a custom looping method, such as using modulus. I aim to display the data in groups of three items, assigning a different class to every 3 items. The desired st ...

Encountering an issue with managing promises in Observables for Angular HTTP Interceptor

Currently, I am encountering the following situation: I have developed an authentication service using Angular/Fire with Firebase authentication. The authentication service is expected to return the ID token through the idToken observable from Angular/Fir ...

Computed properties are not being updated based on changes in the length of the Vuex state object

I'm attempting to retrieve the length of a state object from a computed property, but for some reason it is not reactive. Here is the structure of the state: state: { user: { cards: {}, } } This is the getter in my store: cardCount(sta ...

When utilizing Axios to upload Base64 data, an [Errno 54] error may occur due to a connection

Currently, I am in the process of developing a web application using VueJS for the front-end and Django (Django Rest Framework) for the back-end. One of the key features of this application is the ability to send a PDF invoice via email. To achieve this, ...

How to Collapse or Expand Grouped Items in Vuetify 2 Data Tables

Currently, in my table, I have multiple items grouped by a string property and all groups are expanded by default. If you would like more information on the tables I am using, please visit https://vuetifyjs.com/en/components/data-tables/#grouped-rows Is ...

Troubleshooting problems with Vue 2, vue-router 2, and Laravel 5.3

Seeking assistance in resolving this console error: Error: router.map is not a function Currently utilizing browserify and laravel5.3 Here is the snippet of my app.js code : import Vue from 'vue/dist/vue.js'; var VueRouter = require('v ...

There is no correlationId found within the realm of node.js

Currently, I am in the process of implementing correlationId functionality using express-correlation-id. I am diligently following the guidelines provided on this page: https://www.npmjs.com/package/express-correlation-id. I have successfully imported the ...

What are the steps to resolving an issue in a Jest unit test?

In my ReactJs/Typescript project, I encountered an issue while running a unit test that involves a reference to a module called nock.js and using jest. Initially, the import statement was causing an error in the .cleanAll statement: import nock from &apos ...

Sorting data by percentages in AngularJS

I am currently facing an issue with sorting percentages in a table column. Despite using methods like parseFloat and other AngularJS (1.5.0) sorting techniques, the percentages are not being sorted as expected. [ {percentage: 8.82} {percentage: 0. ...

Having trouble with importing files from a different folder in a React Typescript project

I have a specific folder arrangement set up https://i.sstatic.net/GFOYv.png My goal is to bring both MessageList.tsx and MessageSent.tsx into my Chat.tsx file // Chat.tsx import React from 'react' import {MessageList, MessageSent} from "./ ...