Zod: Establishing minimum and maximum values after converting a string to a numerical value

When dealing with a number or numeric string, I aim to convert it to a number and then validate it using the .min() and .max() methods. However, the results are not matching my expectations.

const numberValid = z.number().or(z.string().regex(/^\d+$/).transform(Number));

const positiveNumber = numberValid.min(0); // Unfortunately, the method does not seem to exist

Answer №1

Starting from version 3.20, you have the ability to utilize z.coerce.number() in this manner:

const validatedNumber = z.coerce.number().min(0)

validatedNumber.parse(123) // Valid
validatedNumber.parse(-123) // Invalid
validatedNumber.parse("123") // Valid
validatedNumber.parse("-123") // Invalid

Answer №2

The issue here is that the transform method is returning a z.ZodEffect, which provides further transformation methods, but loses the original type information of z.string. As a result, the min method from z.number is not accessible because the outer type is z.ZodUnion, which does not recognize the min refinement.

To achieve the desired behavior, you could consider the following approach:

const thing = z
  .number()
  .or(z.string().regex(/\d+/).transform(Number))
  .refine((n) => n >= 0);

Although this solution may seem somewhat lacking, as it does not allow for using min with its simplified syntax and clearer error messages, you could address this by providing a custom message like

{ message: 'value was less than 0' }
as the second argument to the refine method.

Edit

Upon further consideration, another approach is possible. You can utilize the preprocess function to preprocess strings before passing them to z.number. By implementing it this way, you can still make use of .min with its detailed error messages and other functionalities.

const numberValid2 = z.preprocess(
  (input) => {
    const processed = z.string().regex(/^\d+$/).transform(Number).safeParse(input);
    return processed.success ? processed.data : input;
  },
  z.number().min(0),
)

Answer №3

 z.word() 
.modify((year) => parseInt(year)) 
.pipe(z.integer().minimum(1900)) 
.modify((year) => year.toString())

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

WebStorm is not implementing the exclude option as specified in the tsconfig.json file

Is there a way to exclude a directory from TypeScript compilation in WebStorm? Despite specifying the exclusion in the tsconfig.json file, it seems that WebStorm doesn't respect the setting and compiles everything in the root directory. However, runn ...

The functionality of the Request interface appears to be malfunctioning

Hey there, I'm currently working on building an API using Express and TypeScript. My goal is to extend the Request object to include a user property. I've done some research on Google and found several posts on StackOverflow that explain how to d ...

Retrieve the formcontrolname property of a FormGroup within a FormArray

I am currently facing an issue with my code. In my FormGroup, I have a FormArray containing 3 FormControls. My goal is to iterate through the FormArray and display the values of each control in a form. However, I am unsure about what to use for the formCon ...

Typescript: require generic types to include specific keys at all times

Is there a way to ensure that the function below only accepts a data object if it contains an id key, and then allows us to access the id from the data object? function someFuntion<T>(data : T){ const id = data['id'] //Error : Element imp ...

Ways to convert a callback-based function into a promise without losing the returned value

After being given access to this API: function doSomeWork(callbacks : { success ?: (result : SuccessCallbackResult) => void, fail ?: (result : FailCallbackResult) => void, complete ?: (result : CompleteCallbackResult) => void }) : Task ...

Using Angular to Bind Checkbox Value in Typescript

I have a challenge of creating a quiz where a card is displayed with 4 questions structured like this: <div class="col-md-6"> <div class="option" id="Answer1"> <label class="Answer1"> <input value= "Answer1" type="checkbox ...

What is the best way to retrieve information from multiple pages of my REST API?

Recently, I integrated a search engine into my application and now I need to gather all the data available for a particular resource, such as all the posts made by a user. The response I receive from my API looks something like this: { "count": 2, ...

Getting a "function is not defined" error in Angular 6 while using it within a nested function

I'm facing an issue related to typescript, where the following code is causing trouble: private loadTeams = function(){ let token = sessionStorage.getItem('token'); if(token !== undefined && token !== null && token ...

Monitor a universal function category

Trying to implement a TypeScript function that takes a single-argument function and returns a modified version of it with the argument wrapped in an object. However, struggling to keep track of the original function's generics: // ts v4.5.5 t ...

How to effectively manage radio buttons in Angular 6

Here are some questions I have listed below. public QandAList = [ { question:{ id: "Q1", query:"What is the capital of France?" }, options:[ { id: "opt1", text: "Paris" }, ...

Encountering issues with bidirectional data binding functionality

I have integrated a pagination component from ng-bootstrap into a generic component that includes a select dropdown to choose the number of items per page. I triggered an event from this generic component and caught it in the parent component (member-list. ...

Discover the steps to update the rows, adjust the number of results, and manage pagination in angular-datatable with an observable as the primary data source

Incorporating angular-datatables into my Angular 7 application has been a challenge, especially when it comes to displaying search results efficiently. Within the request-creation-component, a search form is generated. Upon clicking the submit button, an ...

Typescript Angular filters stop functioning properly post minification

I developed an angular filter using TypeScript that was functioning properly until I decided to minify the source code. Below is the original filter: module App.Test { export interface IGroupingFilter extends ng.IFilterService { (name:"group ...

Issue with calling a function to change the CSS color class of a button in Angular

Within my Angular code, I am attempting to set a CSS color for my button by calling a TypeScript function that will return the appropriate CSS class name. This is the code I have tried: <button style="height: 10%" class="getColor(days.date)">{{days ...

The server is not allowing the requested method through HTTP POST and therefore returning

Excuse me if this question sounds beginner or if my terminology is incorrect, because I am new to this. I have created a basic Python API for reading and writing to a database (CSV file) with Angular 5 as my front end. While I was able to successfully ret ...

Troubleshooting Appium error management is ineffective

As a newcomer to appium, I might have made some mistakes. I'm encountering a problem with appium while using wdio and jasmine. it('wtf', (done) => { client.init().element('someName').getText() // ^ here ...

What could be causing the error in Angular Universal Server Side Rendering after deployment on Firebase Hosting?

Currently immersed in Angular development utilizing third-party libraries such as Angular CLI/Angular Universal, following the guidelines laid out here. Also, integrating Firebase hosting and real-time database. The application works flawlessly on my local ...

How to retrieve the value of a selected item in primeng using p-dropdown and angular

Encountering an issue when trying to send the selected item value while iterating over an array of strings like: "BMW", "FERRARI", "AUDI", "BENTLY" Here is the structure of my HTML: <p-dropdown optionLabel="type" [options]="cars" formControlName="name" ...

Strange activities observed during the management of state in react hooks, where the splice() function ends up eliminating the

My current setup involves maintaining a state to handle the addition of new JSX elements: const [display, setDisplay] = useState<IDisplay>({ BookingFormDropDown: [], } ); I have a function in onClick() which adds an elem ...

Transforming the Server-side model to the Client-side model within Angular 4

My Server-side C# model public class Instructor:Entity { public string Name { get; set; } public string PhoneNo { get; set; } } Client-side TypeScript model export class Instructor extends Entity { public name:string; public address ...