Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I cast NextJS router.query as a number?

const router = useRouter()
const { photoId } = router.query

I get this Typescript warning when doing a comparison:

TS2367: This condition will always return 'false' since the types 'number' and 'string | string[]' have no overlap.

This makes perfect sense, so I typecast my variable like this:

const router = useRouter()
const { photoId } = parseInt(router.query, 10)

But now I get this warning:

TS2345: Argument of type 'ParsedUrlQuery' is not assignable to parameter of type 'string'.

When I look at the source code for NextJS router, I see this:

interface ParsedUrlQuery extends NodeJS.Dict<string | string[]> { }

Which looks like I'm pretty close to getting what I need, which is just a string instead of a string or array of strings. Where do I go from here?

like image 691
Citizen Avatar asked Jan 12 '21 22:01

Citizen


People also ask

How do I get a router query in next JS?

Method 2: Using withRouter() Method: You can easily get the current router value in react class component using the withRouter(). To use this you just have to export your class component inside withRouter().

How do I query my next router?

If you are passing multiple query parameters to a URL using the & (and) operator. You can access it inside the <Items> component like this. import React, { Component } from "react"; import { withRouter } from "next/router" class Items extends Component { render() { const { query } = this.

Why would withRouter router query be empty on first render in Nextjs?

Pages that are statically optimized by Automatic Static Optimization will be hydrated without their route parameters provided, i.e query will be an empty object ( {} ). Save this answer.

What is shallow routing?

Shallow routing allows you to change the URL without running data fetching methods again, that includes getServerSideProps , getStaticProps , and getInitialProps . You'll receive the updated pathname and the query via the router object (added by useRouter or withRouter ), without losing state.


2 Answers

You can tell compiler how the variable should be treated:

const photoId = parseInt(router.query.photoId as string, 10)

Note that attributes of router.query can be undefined.

like image 179
Nikolai Kiselev Avatar answered Sep 18 '22 08:09

Nikolai Kiselev


One solution would be doing a casting in this way:

const photoId = router.query.photoId ? +router.query.photoId : undefined;

Query props might be undefined, so you first check if it's defined, the use the unary operator, or just return the undefined. The type of integer would be number | undefined. Of course, keep in mind if the photoId is value that can be converted to number.

I always try to refrain from using as as typescript is already unsound, so this isn't adding an extra "trustiness" to the type system itself.

like image 32
Lukas Bobinas Avatar answered Sep 21 '22 08:09

Lukas Bobinas