Skip to content

Commit

Permalink
fix: improve the Option type for transitions (#410)
Browse files Browse the repository at this point in the history
* feat: Add support for transitions

This lets non-shallow updates be notified of server rendering
loading status, using an external `React.useTransition` hook.

* fix: improve typing

* fix: better typing

* fix: remove unnecessary code

* chore: remove unnecessary changes

* fix: some edge cases when shallow is not a boolean type

* fix: remove as any

* fix: e2e build

* chore: better name for generic

* fix: parser type

* fix: better naming

* fix: better naming

* chore: better naming

* test: Add type tests for shallow/startTransition interaction

* fix: simplify type

* test: add a extra test case

* chore: extract type exclusion logic

* chore: simplify types

* chore: remove unnecessary generics

* chore: add test case for startTransition

* test: Add type tests

* chore: Simplify type & prettify

---------

Co-authored-by: Francois Best <[email protected]>
  • Loading branch information
Talent30 and franky47 authored Nov 23, 2023
1 parent 523a273 commit 885317c
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 8 deletions.
16 changes: 13 additions & 3 deletions packages/next-usequerystate/src/defs.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import { useRouter } from 'next/navigation.js' // https://github.com/47ng/next-usequerystate/discussions/352
import type { TransitionStartFunction } from 'react'

export type Router = ReturnType<typeof useRouter>

export type HistoryOptions = 'replace' | 'push'

export type Options = {
// prettier-ignore
type StartTransition<T> = T extends false
? TransitionStartFunction
: T extends true
? never
: TransitionStartFunction

export type Options<Shallow = unknown> = {
/**
* How the query update affects page history
*
Expand All @@ -29,7 +37,7 @@ export type Options = {
* Setting it to `false` will trigger a network request to the server with
* the updated querystring.
*/
shallow?: boolean
shallow?: Extract<Shallow | boolean, boolean>

/**
* Maximum amount of time (ms) to wait between updates of the URL query string.
Expand All @@ -48,8 +56,10 @@ export type Options = {
* `React.useTransition()` hook.
*
* Using this will set the `shallow` setting to `false` automatically.
* As a result, you can't set both `shallow: true` and `startTransition`
* in the same Options object.
*/
startTransition?: React.TransitionStartFunction
startTransition?: StartTransition<Shallow>
}

export type Nullable<T> = {
Expand Down
2 changes: 1 addition & 1 deletion packages/next-usequerystate/src/parsers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export type ParserBuilder<T> = Required<Parser<T>> &
* Note that you can override those options in individual calls to the
* state updater function.
*/
withOptions<This>(this: This, options: Options): This
withOptions<This, Shallow>(this: This, options: Options<Shallow>): This

/**
* Specifying a default value makes the hook state non-nullable when the
Expand Down
49 changes: 48 additions & 1 deletion packages/next-usequerystate/src/tests/parsers.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { expectType } from 'tsd'
import { expectError, expectType } from 'tsd'
import { parseAsString } from '../../dist'

{
Expand Down Expand Up @@ -27,3 +27,50 @@ import { parseAsString } from '../../dist'
expectType<string | null>(p.parse('foo'))
expectType<string>(p.parseServerSide(undefined))
}

// Shallow / startTransition interaction
{
type RSTF = React.TransitionStartFunction
type MaybeBool = boolean | undefined
type MaybeRSTF = RSTF | undefined

expectType<MaybeBool>(parseAsString.withOptions({}).shallow)
expectType<MaybeRSTF>(parseAsString.withOptions({}).startTransition)
expectType<MaybeBool>(parseAsString.withOptions({ shallow: true }).shallow)
expectType<MaybeRSTF>(
parseAsString.withOptions({ shallow: true }).startTransition
)
expectType<MaybeBool>(parseAsString.withOptions({ shallow: false }).shallow)
expectType<MaybeRSTF>(
parseAsString.withOptions({ shallow: false }).startTransition
)
expectType<MaybeBool>(
parseAsString.withOptions({ startTransition: () => {} }).shallow
)
expectType<MaybeRSTF>(
parseAsString.withOptions({ startTransition: () => {} }).startTransition
)
// Allowed
parseAsString.withOptions({
shallow: false,
startTransition: () => {}
})
// Not allowed
expectError(() => {
parseAsString.withOptions({
shallow: true,
startTransition: () => {}
})
})
expectError(() => {
parseAsString.withOptions({
shallow: {}
})
})

expectError(() => {
parseAsString.withOptions({
startTransition: {}
})
})
}
14 changes: 14 additions & 0 deletions packages/next-usequerystate/src/tests/useQueryState.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -290,3 +290,17 @@ import {
expectError(() => setFoo(() => undefined))
expectError(() => setBar(() => undefined))
}

// Shallow & startTransition interaction
{
const [, set] = useQueryState('foo')
set('ok', { shallow: true })
set('ok', { shallow: false })
set('ok', { startTransition: () => {} })
expectError(() => {
set('nope', {
shallow: true,
startTransition: () => {}
})
})
}
8 changes: 5 additions & 3 deletions packages/next-usequerystate/src/useQueryState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ export type UseQueryStateReturn<Parsed, Default> = [
Default extends undefined
? Parsed | null // value can't be null if default is specified
: Parsed,
(
<Shallow>(
value:
| null
| Parsed
| ((
old: Default extends Parsed ? Parsed : Parsed | null
) => Parsed | null),
options?: Options
options?: Options<Shallow>
) => Promise<URLSearchParams>
]

Expand Down Expand Up @@ -206,7 +206,9 @@ export function useQueryState<T = string>(
serialize = String,
defaultValue = undefined,
startTransition
}: Partial<UseQueryStateOptions<T>> & { defaultValue?: T } = {
}: Partial<UseQueryStateOptions<T>> & {
defaultValue?: T
} = {
history: 'replace',
scroll: false,
shallow: true,
Expand Down

0 comments on commit 885317c

Please sign in to comment.