[Vuejs]-Generating types out of vue-router route[x].name

0👍

Try satisfies RouteRecordRaw[] instead of as const.

You’ll get the same type deduction, but ts won’t yell at you for the extra readonlys

0👍

Here’s one approach to make sure that all the types are satisfied and yet you get 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;

With this approach, you can provide any string for path & name and yet get intellisense for the string you add to types Path and Names. Let me know if I missed something or if doesn’t meet your requirements.

Example

Note: you may not get intellisense in Stackblitz with this, however, you’ll get it in your IDE, like VSCode. That’s just so, because of Stackblitz limitation.

Leave a comment