Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
{
"label": "Backlog",
"query": "repo:47ng/nuqs is:pr is:open milestone:\"🪵 Backlog\""
}
},
],
"githubIssues.queries": [
{
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -743,7 +743,7 @@ const searchParams = {
limit: parseAsInteger,
from: parseAsIsoDateTime,
to: parseAsIsoDateTime,
sortBy: parseAsStringLiteral(['asc', 'desc'] as const)
sortBy: parseAsStringLiteral(['asc', 'desc'])
}

// Create a serializer function by passing the description of the search params to accept
Expand Down
21 changes: 17 additions & 4 deletions packages/docs/content/docs/parsers/built-in.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,19 @@ These parsers extend the basic integer and float parsers, but test against
some expected valid values, defined as [TypeScript literals](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).

<Callout title="Note">
Don't forget the `as const{:ts}` when declaring your expected values.
If declaring your expected values outside of the parser, don't forget to add `as const{:ts}`.
</Callout>

```ts
import { parseAsStringLiteral, inferParserType } from 'nuqs'

// Create parser
const parser = parseAsStringLiteral(['asc', 'desc'])

// Optional: extract the type
type SortOrder = inferParserType<typeof parser> // 'asc' | 'desc'
```

### String literals

```ts /as const/
Expand All @@ -152,9 +162,6 @@ const sortOrder = ['asc', 'desc'] as const

// Then pass it to the parser
parseAsStringLiteral(sortOrder)

// Optional: extract the type from them
type SortOrder = (typeof sortOrder)[number] // 'asc' | 'desc'
```

<Suspense fallback={<DemoFallback />}>
Expand All @@ -163,6 +170,12 @@ type SortOrder = (typeof sortOrder)[number] // 'asc' | 'desc'

### Numeric literals

```ts
import { parseAsNumberLiteral } from 'nuqs'

parseAsNumberLiteral([1, 2, 3, 4, 5, 6])
```

```ts /as const/
import { parseAsNumberLiteral } from 'nuqs'

Expand Down
2 changes: 1 addition & 1 deletion packages/docs/content/docs/parsers/demos.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ export function BooleanParserDemo() {
export function StringLiteralParserDemo() {
const [value, setValue] = useQueryState(
'sort',
parseAsStringLiteral(['asc', 'desc'] as const)
parseAsStringLiteral(['asc', 'desc'])
)
return (
<DemoContainer demoKey="sort">
Expand Down
2 changes: 1 addition & 1 deletion packages/docs/content/docs/utilities.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const searchParams = {
limit: parseAsInteger,
from: parseAsIsoDateTime,
to: parseAsIsoDateTime,
sortBy: parseAsStringLiteral(['asc', 'desc'] as const)
sortBy: parseAsStringLiteral(['asc', 'desc'])
}

// Create a serializer function by passing the description of the search params to accept
Expand Down
4 changes: 2 additions & 2 deletions packages/e2e/shared/specs/render-count.params.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ const params = {
hook: parseAsStringLiteral([
'useQueryState',
'useQueryStates'
] as const).withDefault('useQueryState'),
]).withDefault('useQueryState'),
shallow: parseAsBoolean.withDefault(true),
history: parseAsStringLiteral(['push', 'replace'] as const).withDefault(
history: parseAsStringLiteral(['push', 'replace']).withDefault(
'replace'
),
startTransition: parseAsBoolean.withDefault(false)
Expand Down
4 changes: 2 additions & 2 deletions packages/e2e/shared/specs/stitching.defs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ export const optionsSearchParams = {
hook: parseAsStringLiteral([
'useQueryState',
'useQueryStates'
] as const).withDefault('useQueryState'),
]).withDefault('useQueryState'),
shallow: parseAsBoolean.withDefault(true),
history: parseAsStringLiteral(['push', 'replace'] as const).withDefault(
history: parseAsStringLiteral(['push', 'replace']).withDefault(
'replace'
)
}
Expand Down
4 changes: 2 additions & 2 deletions packages/nuqs/src/parsers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ describe('parsers', () => {
expect(isParserBijective(parser, 'b', Test.B)).toBe(true)
})
it('parseAsStringLiteral', () => {
const parser = parseAsStringLiteral(['a', 'b', 'c'] as const)
const parser = parseAsStringLiteral(['a', 'b', 'c'])
expect(parser.parse('')).toBeNull()
expect(parser.parse('a')).toBe('a')
expect(parser.parse('b')).toBe('b')
Expand All @@ -171,7 +171,7 @@ describe('parsers', () => {
expect(isParserBijective(parser, 'c', 'c')).toBe(true)
})
it('parseAsNumberLiteral', () => {
const parser = parseAsNumberLiteral([1, 2, 3] as const)
const parser = parseAsNumberLiteral([1, 2, 3])
expect(parser.parse('')).toBeNull()
expect(parser.parse('1')).toBe(1)
expect(parser.parse('2')).toBe(2)
Expand Down
4 changes: 2 additions & 2 deletions packages/nuqs/src/parsers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ export function parseAsStringEnum<Enum extends string>(
*
* @param validValues The values you want to accept
*/
export function parseAsStringLiteral<Literal extends string>(
export function parseAsStringLiteral<const Literal extends string>(
validValues: readonly Literal[]
): ParserBuilder<Literal> {
return createParser({
Expand Down Expand Up @@ -361,7 +361,7 @@ export function parseAsStringLiteral<Literal extends string>(
*
* @param validValues The values you want to accept
*/
export function parseAsNumberLiteral<Literal extends number>(
export function parseAsNumberLiteral<const Literal extends number>(
validValues: readonly Literal[]
): ParserBuilder<Literal> {
return createParser({
Expand Down
4 changes: 2 additions & 2 deletions packages/nuqs/tests/parsers.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,13 @@ describe('types/parsers', () => {
assertType<Test | null>(p.parseServerSide(undefined))
})
test('parseAsStringLiteral', () => {
const p = parseAsStringLiteral(['a', 'b'] as const)
const p = parseAsStringLiteral(['a', 'b'])
assertType<'a' | 'b' | null>(p.parse('a'))
assertType<string>(p.serialize('a'))
assertType<'a' | 'b' | null>(p.parseServerSide(undefined))
})
test('parseAsNumberLiteral', () => {
const p = parseAsNumberLiteral([1, 2, 3] as const)
const p = parseAsNumberLiteral([1, 2, 3])
assertType<1 | 2 | 3 | null>(p.parse('42'))
assertType<string>(p.serialize(1))
assertType<1 | 2 | 3 | null>(p.parseServerSide(undefined))
Expand Down