question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Built-in type coercion support

See original GitHub issue

Would you be open to a PR, providing built-in implementation for processors, performing coercion to most common types? (numbers, string, booleans, arrays)?

This is how type coercion looks like right now:

        const preprocessor = (value) => {
            switch (typeof value) {
                case 'bigint':
                case 'boolean':
                case 'number':
                    return value.toString();

                case 'object':
                    if (value == null) {
                        return value;
                    }
                    if (value instanceof Date) {
                        return value.toISOString();
                    }
                    return value; // could not coerce, return the original and face the consequences during validation

                case 'string':
                    return value.trim();

                case 'undefined':
                    return value;

                default:
                    return value; // could not coerce, return the original and face the consequences during validation
            }
        }

        const CREATE_USER_SCHEMA = z.object({
            age: z.preprocess(preprocessor, z.string().max(15))
        })

        const result = CREATE_USER_SCHEMA.parse({
            age: 44
        });

        expect(result).toEqual({
            age: '44'
        })

This is pretty verbose and requires plenty of boilerplate every time.

This is a proposed API:

        const CREATE_USER_SCHEMA = z.object({
            age: z.string().max(3).coerce()
        })

        const result = CREATE_USER_SCHEMA.parse({
            age: 44
        });

        expect(result).toEqual({
            age: '44'
        })

Resolution of a specific preprocessor would be based on ZodType typeName, and throw an error if no preprocessor is implemented for a given type.

Issue Analytics

  • State:open
  • Created a year ago
  • Reactions:5
  • Comments:7 (1 by maintainers)

github_iconTop GitHub Comments

6reactions
colinhackscommented, Aug 8, 2022

I’ll look into this in the near future. This decision is intertwined with the idea of some sort of “pipeline” feature:

z.string().transform(val => val.length).pipe(z.number()).min(5);

So hold off on the PR until I do some experiments on the feasibility of that.

4reactions
abenhamdinecommented, Aug 25, 2022

This feature would be useful, and is implemented in some of other validation libraries. For example, by default, joi.validate coerce values before validating : https://joi.dev/api/?v=17.6.0
image

Superstruct also handles coercion by default : https://docs.superstructjs.org/api-reference/coercions Same for yup : it coerces values except if you use strict option : https://github.com/jquense/yup#schemastrictenabled-boolean--false-schema

Actually, when I have used zod the first time, I was surprised to run into an error when trying to parse a string like “12” as a number.

This would be very useful when you want to validate FormData (as in Remix), because in FormData, everything is a string.

Currently, we have to coerce manually the numbers, or use a wrapper on zod to coerce values like https://github.com/airjp73/remix-validated-form/tree/main/packages/zod-form-data but it’s not ideal, because it adds a layer of complexity, and generators like zod-prisma don’t take in account these kind of libraries.

Additional note :

I note this approach has been considered in https://github.com/colinhacks/zod/issues/100 :

image

but eventually it seems that only the “postprocessing” part has been kept.

Read more comments on GitHub >

github_iconTop Results From Across the Web

JavaScript type coercion explained
Type coercion is the process of converting value from one type to another (such as string to number, object to boolean, and so...
Read more >
Type Coercion - Apache Tapestry
Type Coercion is the conversion of one type of object to a another object of a different type with similar content. Tapestry frequently...
Read more >
Type coercion in JavaScript
Type coercion in JavaScript only coerces to the string , number , and Boolean primitive types. There's no way in JavaScript to coerce...
Read more >
2 Type coercion in JavaScript
2.2 Operations that help implement coercion in the ECMAScript specification ... At the moment, JavaScript has two built-in numeric types: number and bigint....
Read more >
Understanding Primitive Type Coercion in JavaScript
All programming languages, including JavaScript (JS), have built-in data types; these include strings, numbers, Dates, Arrays, and so forth.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found