ParsedUrlQuery typings should allow undefined values
See original GitHub issueBug report
Describe the bug
I am not sure if this is an upstream bug or not. This is about the ctx.query
object.
The type ParsedUrlQuery
exported from @types/node/querystring
looks wrong. It is string | string[]
but in theory could be undefined
as well.
To Reproduce
// /user.tsx
UserPage.getInitialProps = async (ctx) => {
const user = ctx.query.user; // CAN be undefined, but is shown as string | string[]
return {
// ...
};
};
Router.push('/user', {
query: {
somethingElse: 'blabla'
// not defining 'user' here
}
})
Expected behavior
The types for the query
object should be less permissive and includes undefined
in order to write safer code.
Screenshots
System information
- OS: n/a
- Browser (if applies): n/a
- Version of Next.js: 6.2.1
Additional context
The current way of solving it is to extend the querystring
module by re-declaring it. It is fine, but annoying.
Issue Analytics
- State:
- Created 4 years ago
- Reactions:4
- Comments:12 (8 by maintainers)
Top Results From Across the Web
ParsedUrlQuery | typescript - v3.7.7
Interface ParsedUrlQuery. Hierarchy. Dict<string | string[]>. ParsedUrlQuery. Indexable. [key: string]: string | string[] | undefined.
Read more >How to deal with TypeScript not treating uninitialized optional ...
What I expect from these function typings is to treat lack of value as undefined , but TypeScript doesn't allow this, and instead...
Read more >Untitled
Through it, we can easily obtain the protocol, host, port, query parameters, ... ParsedUrlQuery typings should allow undefined values #10284 Closed martpie ...
Read more >TypeScript Null & Undefined - W3Schools
TypeScript has a powerful system to deal with null or undefined values. By default null and undefined handling is disabled, and can be...
Read more >Next.js dynamic routes & Typescript - J Paul Lescouzères
It also allows us to create dynamic routes, based on query params (eg blog posts). ... 1Property 'slug' does not exist on type...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
@neefrehman You’re welcome. You can use the type guard once and anything that comes after in the same context will be considered a string:
The type assertion in your example is a risky approach because it can still lead to errors. For example,
/^[0-9]{6}$/).test(["123456"])
will returntrue
, and any code that depends on sketchId being a string without checking will fail.In my own code, whenever I feel the need to use a forced type assertion, it usually means that I am missing a necessary check or need to change my logic flow. I only use it as a last resort when I know that I am being smarter than TypeScript.
I’m having a related issue when trying to extract a query in a dynamic route. I’m destructuring a variable (which will be a string) from the
router.query
object, which later I’ll need to use some string-specific properties on such as.substr
. I’m getting errors from this as the variable could also be of typestring[]
:When trying to be explicit about the type, I’m getting another saying that I cant assign type
string
toParsedUrlQuery
(renaming the variable in the destructuring assignment doesn’t cause the issue):Currently the only workaround is to assign a type of
any
, which isn’t ideal:const { sketch: sketchId }: any = router.query;
Is there a way to assign a type of only
string
to the returned variable so I can continue treating it as such?Happy to open another issue if needed, but I felt this one was close! I’m currently on the most up-to-date typings.