@@ -40,6 +40,27 @@ export type ParserBuilder<T> = Required<Parser<T>> &
4040 */
4141 withOptions < This , Shallow > ( this : This , options : Options < Shallow > ) : This
4242
43+ /**
44+ * Pass in a validation function to perform runtime checks on the parsed
45+ * value. If the validation fails, the value will be set to `null` (or
46+ * the default value if specified).
47+ *
48+ * Validation must be synchronous, and must throw an error on invalid
49+ * inputs.
50+ *
51+ * Example with Zod:
52+ * ```ts
53+ * const [posInt, setPosInt] = useQueryState(
54+ * 'value',
55+ * parseAsInteger.withValidation(z.number().positive().parse)
56+ * )
57+ * ```
58+ *
59+ * @param this
60+ * @param validate
61+ */
62+ withValidation < This > ( this : This , validate : ( input : unknown ) => T ) : This
63+
4364 /**
4465 * Specifying a default value makes the hook state non-nullable when the
4566 * query is missing from the URL.
@@ -119,6 +140,18 @@ export function createParser<T>(
119140 eq : ( a , b ) => a === b ,
120141 ...parser ,
121142 parseServerSide : parseServerSideNullable ,
143+ withValidation ( validate ) {
144+ return {
145+ ...this ,
146+ parse : ( value : string ) => {
147+ const parsed = parser . parse ( value )
148+ if ( parsed === null ) {
149+ return null
150+ }
151+ return validate ( parsed )
152+ }
153+ }
154+ } ,
122155 withDefault ( defaultValue ) {
123156 return {
124157 ...this ,
@@ -128,7 +161,7 @@ export function createParser<T>(
128161 }
129162 }
130163 } ,
131- withOptions ( options : Options ) {
164+ withOptions ( options ) {
132165 return {
133166 ...this ,
134167 ...options
0 commit comments