Skip to content

Commit

Permalink
fix(ts): ReadonlyURLSearchParams should extend URLSearchParams (#…
Browse files Browse the repository at this point in the history
…61419)

### What?

Let the developer check the instance of `ReadonlyURLSearchParams` to
match against `URLSearchParams`

### Why?

`useSearchParams()`'s return type is `ReadonlyURLSearchParams` which
implements all the methods of `URLSearchParams`, therefore its type
should be extended from `URLSearchParams` as well. Deprecated methods
are also implemented to throw an error, so no runtime behavior is being
changed

### How?

Mark the unavailable methods as `@deprecated` which will visually mark
them in IDEs:


![image](https://github.com/vercel/next.js/assets/18369201/f3de2858-14ac-4021-981d-b0267610faa7)

This is similar how `ReadonlyHeaders` extends `Headers`, added in:
#49075

[Slack
thread](https://vercel.slack.com/archives/C03KAR5DCKC/p1706628877916779)

Closes NEXT-2305
  • Loading branch information
balazsorban44 authored Feb 6, 2024
1 parent da842e1 commit df74a02
Showing 1 changed file with 16 additions and 40 deletions.
56 changes: 16 additions & 40 deletions packages/next/src/client/components/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,55 +15,31 @@ import { clientHookInServerComponentError } from './client-hook-in-server-compon
import { getSegmentValue } from './router-reducer/reducers/get-segment-value'
import { PAGE_SEGMENT_KEY, DEFAULT_SEGMENT_KEY } from '../../shared/lib/segment'

const INTERNAL_URLSEARCHPARAMS_INSTANCE = Symbol(
'internal for urlsearchparams readonly'
)

function readonlyURLSearchParamsError() {
return new Error('ReadonlyURLSearchParams cannot be modified')
}

export class ReadonlyURLSearchParams {
[INTERNAL_URLSEARCHPARAMS_INSTANCE]: URLSearchParams

entries: URLSearchParams['entries']
forEach: URLSearchParams['forEach']
get: URLSearchParams['get']
getAll: URLSearchParams['getAll']
has: URLSearchParams['has']
keys: URLSearchParams['keys']
values: URLSearchParams['values']
toString: URLSearchParams['toString']
size: any | URLSearchParams['size']

constructor(urlSearchParams: URLSearchParams) {
this[INTERNAL_URLSEARCHPARAMS_INSTANCE] = urlSearchParams

this.entries = urlSearchParams.entries.bind(urlSearchParams)
this.forEach = urlSearchParams.forEach.bind(urlSearchParams)
this.get = urlSearchParams.get.bind(urlSearchParams)
this.getAll = urlSearchParams.getAll.bind(urlSearchParams)
this.has = urlSearchParams.has.bind(urlSearchParams)
this.keys = urlSearchParams.keys.bind(urlSearchParams)
this.values = urlSearchParams.values.bind(urlSearchParams)
this.toString = urlSearchParams.toString.bind(urlSearchParams)
this.size = urlSearchParams.size
}
[Symbol.iterator]() {
return this[INTERNAL_URLSEARCHPARAMS_INSTANCE][Symbol.iterator]()
/** @internal */
class ReadonlyURLSearchParamsError extends Error {
constructor() {
super(
'Method unavailable on `ReadonlyURLSearchParams`. Read more: https://nextjs.org/docs/app/api-reference/functions/use-search-params#updating-searchparams'
)
}
}

export class ReadonlyURLSearchParams extends URLSearchParams {
/** @deprecated Method unavailable on `ReadonlyURLSearchParams`. Read more: https://nextjs.org/docs/app/api-reference/functions/use-search-params#updating-searchparams */
append() {
throw readonlyURLSearchParamsError()
throw new ReadonlyURLSearchParamsError()
}
/** @deprecated Method unavailable on `ReadonlyURLSearchParams`. Read more: https://nextjs.org/docs/app/api-reference/functions/use-search-params#updating-searchparams */
delete() {
throw readonlyURLSearchParamsError()
throw new ReadonlyURLSearchParamsError()
}
/** @deprecated Method unavailable on `ReadonlyURLSearchParams`. Read more: https://nextjs.org/docs/app/api-reference/functions/use-search-params#updating-searchparams */
set() {
throw readonlyURLSearchParamsError()
throw new ReadonlyURLSearchParamsError()
}
/** @deprecated Method unavailable on `ReadonlyURLSearchParams`. Read more: https://nextjs.org/docs/app/api-reference/functions/use-search-params#updating-searchparams */
sort() {
throw readonlyURLSearchParamsError()
throw new ReadonlyURLSearchParamsError()
}
}

Expand Down

0 comments on commit df74a02

Please sign in to comment.