vuejs / router

🚦 The official router for Vue.js
https://router.vuejs.org/
MIT License
3.95k stars 1.19k forks source link

Support Type Augmentation for LocationQuery and LocationQueryRaw in Vue Router #2407

Closed TNGD-YQ closed 4 days ago

TNGD-YQ commented 4 days ago

What problem is this solving

Currently, I am using vue-router with TypeScript face limitations when attempting to extend or customize the LocationQuery and LocationQueryRaw types. These types are defined as type aliases, which restrict direct augmentation, making it challenging to enforce stricter type safety for route queries.

Use Case Scenario:

const searchByKeyword = (keyword: string) => {
  return keyword
}

// Problem #1: I know the keyword is always a string, I don't want to keep casting it to string
searchByKeyword(router.currentRoute.value.query.search as string)

// Problem #2: My colleague introduce a new query param, but I don't know what it is
router.currentRoute.value.query.something

By enabling type augmentation for LocationQuery and LocationQueryRaw, I can define global typings for route queries, ensuring consistent and type-safe access across the entire application.

import "vue-router"

export interface CustomQuery {
  /**
   * Used in search page to filter the search results
   */
  search?: string
  /**
   * Used in search and home page, to indicate a specific purpose
   *
   * @example "home" | "search" | "category"
   */
  something?: string
}

declare module "vue-router" {
  interface LocationQuery extends CustomQuery {}

  interface LocationQueryRaw extends CustomQuery {}
}

image

Proposed solution

Before:

export declare type LocationQuery = Record<string, LocationQueryValue | LocationQueryValue[]>;

export declare type LocationQueryRaw = Record<string | number, LocationQueryValueRaw | LocationQueryValueRaw[]>;

After

export declare interface LocationQuery  {
    [x: string]: LocationQueryValue | LocationQueryValue[]
};

export declare interface LocationQueryRaw {
    [x: string | number]: LocationQueryValueRaw | LocationQueryValueRaw[]
};

Describe alternatives you've considered

No response

posva commented 4 days ago

What you are proposing is not type safe BUT there are ongoing plans to add support to extract and parse in a type safe way, query params as params 😄 Keep a look for the next Vue Router and new matchers