Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(serializer/types): Allow null value in serializer for parsers with default values #769

Merged
merged 3 commits into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions packages/nuqs/src/parsers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -421,13 +421,13 @@ export function parseAsArrayOf<ItemType>(
}

type inferSingleParserType<Parser> = Parser extends ParserBuilder<
infer Type
infer Value
> & {
defaultValue: infer Type
defaultValue: infer Value
}
? Type
: Parser extends ParserBuilder<infer Type>
? Type | null
? Value
: Parser extends ParserBuilder<infer Value>
? Value | null
: never
franky47 marked this conversation as resolved.
Show resolved Hide resolved

type inferParserRecordType<Map extends Record<string, ParserBuilder<any>>> = {
Expand Down
14 changes: 14 additions & 0 deletions packages/nuqs/src/serializer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,20 @@ describe('serializer', () => {
const result = serialize('?str=foo&external=kept', null)
expect(result).toBe('?external=kept')
})
test('clears value when setting null for search param that has a default value', () => {
const serialize = createSerializer({
int: parseAsInteger.withDefault(0)
})
const result = serialize('?int=1&str=foo', { int: null })
expect(result).toBe('?str=foo')
})
test('clears value when setting null for search param that is set to its default value', () => {
const serialize = createSerializer({
int: parseAsInteger.withDefault(0)
})
const result = serialize('?int=0&str=foo', { int: null })
expect(result).toBe('?str=foo')
})
franky47 marked this conversation as resolved.
Show resolved Hide resolved
test('clears value when setting the default value (`clearOnDefault: true` is the default)', () => {
const serialize = createSerializer({
int: parseAsInteger.withDefault(0),
Expand Down
4 changes: 2 additions & 2 deletions packages/nuqs/src/serializer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Options } from './defs'
import type { Nullable, Options } from './defs'
import type { inferParserType, ParserBuilder } from './parsers'
import { renderQueryString } from './url-encoding'

Expand All @@ -16,7 +16,7 @@ export function createSerializer<
urlKeys?: Partial<Record<keyof Parsers, string>>
} = {}
) {
type Values = Partial<inferParserType<Parsers>>
type Values = Partial<Nullable<inferParserType<Parsers>>>

/**
* Generate a query string for the given values.
Expand Down
13 changes: 13 additions & 0 deletions packages/nuqs/src/tests/serializer.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,16 @@ import { createSerializer, parseAsInteger, parseAsString } from '../../dist'
serialize({ nope: null })
})
}

// It accepts null for values
{
const serialize = createSerializer({
foo: parseAsInteger,
bar: parseAsInteger.withDefault(0)
})
// Should accept number | null | undefined
expectType<string>(serialize({ foo: null }))
expectType<string>(serialize({ foo: undefined }))
expectType<string>(serialize({ bar: null }))
expectType<string>(serialize({ bar: undefined }))
franky47 marked this conversation as resolved.
Show resolved Hide resolved
}
Loading