@@ -17,6 +17,27 @@ export type ParserBuilder<T> = Required<Parser<T>> &
1717 */
1818 withOptions < This , Shallow > ( this : This , options : Options < Shallow > ) : This
1919
20+ /**
21+ * Pass in a validation function to perform runtime checks on the parsed
22+ * value. If the validation fails, the value will be set to `null` (or
23+ * the default value if specified).
24+ *
25+ * Validation must be synchronous, and must throw an error on invalid
26+ * inputs.
27+ *
28+ * Example with Zod:
29+ * ```ts
30+ * const [posInt, setPosInt] = useQueryState(
31+ * 'value',
32+ * parseAsInteger.withValidation(z.number().positive().parse)
33+ * )
34+ * ```
35+ *
36+ * @param this
37+ * @param validate
38+ */
39+ withValidation < This > ( this : This , validate : ( input : unknown ) => T ) : This
40+
2041 /**
2142 * Specifying a default value makes the hook state non-nullable when the
2243 * query is missing from the URL.
@@ -93,6 +114,18 @@ export function createParser<T>(parser: Required<Parser<T>>): ParserBuilder<T> {
93114 return {
94115 ...parser ,
95116 parseServerSide : parseServerSideNullable ,
117+ withValidation ( validate ) {
118+ return {
119+ ...this ,
120+ parse : ( value : string ) => {
121+ const parsed = parser . parse ( value )
122+ if ( parsed === null ) {
123+ return null
124+ }
125+ return validate ( parsed )
126+ }
127+ }
128+ } ,
96129 withDefault ( defaultValue ) {
97130 return {
98131 ...this ,
@@ -102,7 +135,7 @@ export function createParser<T>(parser: Required<Parser<T>>): ParserBuilder<T> {
102135 }
103136 }
104137 } ,
105- withOptions ( options : Options ) {
138+ withOptions ( options ) {
106139 return {
107140 ...this ,
108141 ...options
0 commit comments