Nullable Yogurt
Nullable Yogurt

Reputation: 267

Is there way to type route.params in Vue.js?

I ran into a trouble while Typescriptizing my vue.js app. I try to pluck a parameter from route.params and assign it to a property of a reactive form. However, TypeScript gave me a warning that the type of parameter must be string|string[], so it can't be assigned to a string property. The only solution I came up with is the following :

form.productId = route.params.productId as string

I think it would be a better solution if I could type parameters of route.params, but I have no idea of how to do it. I would appreciate it if someone can help on this.

Upvotes: 13

Views: 9105

Answers (2)

John Devitt
John Devitt

Reputation: 736

Zod would be a useful solution here.

import { z } from "zod";

const stringSchema = z.string();
const productId = stringSchema.parse(router.params.productId)

Zod then throws an error if router.params.productId is not a string, which is likely what you'd do either way with the type guard approach.

Typescript can only do type inference at compile time. Data from the URL, API, files, etc. can only be known at runtime. The pattern of "check the data matches a certain shape, throw an error if not" can fill in the runtime gap in Typescript

Upvotes: 0

tao
tao

Reputation: 90168

The route.params are already typed, which is why you're seeing the warning.

Their type is string | string[], because a route can have a param multiple times, which internally gets transformed into an array of strings.

There are a couple of proper solutions:

  1. if you know this param will never be provided more than once in an URL, and it will always be provided on this particular route, you have to pass this information to TypesScript, by casting
const productId = router.params.productId as string
// from here on `productId` is treated as string

  1. If the parameter could be provided multiple times and/or could be missing, use type guards to deal with each case:
const { productId } = router.params

if (typeof productId === "string") {
  // treat `productId` as string
} else if (Array.isArray(productId)) {
  // treat `productId` as string[]
} else {
  // treat `productId` as undefined
}

Upvotes: 13

Related Questions