question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

ParsedUrlQuery typings should allow undefined values

See original GitHub issue

Bug 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

Screen Shot 2020-01-27 at 16 09 10

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:closed
  • Created 4 years ago
  • Reactions:4
  • Comments:12 (8 by maintainers)

github_iconTop GitHub Comments

3reactions
msheakoskicommented, Apr 30, 2020

@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:

const sketchId = isString(router.query.sketch) ? router.query.sketch : ""
// or inline the check
const sketchId = typeof router.query.sketch === "string" ? router.query.sketch : ""

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 return true, 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.

2reactions
neefrehmancommented, Apr 30, 2020

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 type string[]:

image

When trying to be explicit about the type, I’m getting another saying that I cant assign type string to ParsedUrlQuery (renaming the variable in the destructuring assignment doesn’t cause the issue):

image

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.

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found