Reputation: 267
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
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
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:
const productId = router.params.productId as string
// from here on `productId` is treated as string
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