ow
ow copied to clipboard
Nullable modifier
ow.nullable.string
instead of
ow.any(ow.string, ow.null)
A generic modifier for |null|undefined
would also be useful. Maybe it is better if optional
will also allow null
? In most cases, you need |null|undefined
and |null
. Separately, |undefined
is needed almost never.
We are unlikely to add this as we feel null
should not be used in general. See: https://github.com/sindresorhus/meta/issues/7
- It is not always possible to refuse null. For example, I check the server response and GraphQL really likes to send null. My server developer are unlikely to be inspired by the idea of abandoning null.
- Sometimes it is possible to use null to your advantage. Example: undefined - data was not requested from server, null - requested, there is no data. This works great for me.
- It is unlikely that more than 5-10 lines of code (without tests) will be required to implement this; this is really a simple functionality.
I'd also like to support the idea of having a nullable
validator. Even though I generally agree with https://github.com/sindresorhus/meta/issues/7, null
is out there in the wild and since dynamic type-checks mostly exist for validating input that is provided at runtime, I feel that we can't just discount null
on the basis of code-style preference.
Originally, I wanted to submit an issue to discuss standardization of exception messages, but having a nullable validator that'd merge the message would work as well.
Current:
ArgumentError: Any predicate failed with the following errors:
- Expected property `foo` to be of type `null` but received type `Object`
- Expected `foo` to be of type `number` but received type `Object` in object
Preferred:
ArgumentError: Expected property `foo` to be of type `number` or `null` but received type `Object`
Sorry for my english and my persistence.
Why not use the following syntax instead of any
:
ow.number.or.string;
? This allows you not to break your fingers once again by typing brackets and solves the problem with null:
ow.number.or.null;
ow.number.or.null.or.undefined;
It is also not clear why need the types for int8Array
, uint8Array
, nan
, etc.? Such libraries are usually used at the junction of code bases. Like the following:
- The client part of the application receives data from the server and checks this data for changes in the API.
- On the contrary: the server checks the incoming parameters to immediately stop processing the request if the parameters are incorrect.
- Data is validated before being sent to the database, for example, in my ORM
joi
is used for this.
In all the above examples, no int8Array is possible. Maybe for smaller size it's better to limit types to possible in json plus undefined and maybe some commonly used types?
UPDATE:
I suddenly read the first line in readme and realized why ow
is what it is. It's just for other tasks. This is the fourth attempt to find a validation library suitable for my tasks. Before that there were type-check
, joi
, yup
. Looks like I'll have to write it himself ((.
UPDATE2: Probably a bit crude implementation, but already quite working: @riim/type.
I have changed my mind. It does indeed make sense to add this here as you can't control what other APIs use. PR welcome.
I still want a link to https://github.com/sindresorhus/meta/issues/7 in the docs to try to convince people to not use null
in their own APIs though.
I wanted to submit an issue to discuss standardization of exception messages
You should still open an issue about this for other use-cases. We've tried to keep the messages consistent, but I'm sure we missed some cases.
Why not use the following syntax instead of any: ow.number.or.string;
I don't remember exactly why we didn't do it this way. It does look nice, but there are ambiguous cases:
ow.string.length(3).and.string.uppercase.or.string.includes('f')
Does this mean it accepts
(ow.string.length(3) && string.uppercase) || string.includes('f')
or
(ow.string.length(3) && (string.uppercase || string.includes('f'))
?
In omyumyum i use .custom()
to transfer priority to .or
. For example, an object may contain either a field age
or field birthday
:
om.object.shape({ name: om.string }).and.custom(
om.object.shape({ age: om.number })
.or.object.shape({ birthday: om.date })]
);