Comments (20)
I think it should be in core. I very often have APIs with an options-object and I want to quickly validate the options. Having to do separate ow
calls for each property would be verbose and annoying.
I think this:
ow(target, ow.object.label('target').shape({
width: ow.number.positive.integer,
height: ow.number.positive.integer,
data: ow.any(ow.uint8Array, ow.uint8ClampedArray)
}))
is better than this:
ow(target, ow.object.label('target'))
ow(target.width, ow.number.positive.integer.label('target.width'))
ow(target.height, ow.number.positive.integer.label('target.height'))
ow(target.data, ow.any(ow.uint8Array, ow.uint8ClampedArray))
We also wouldn't need label()
for the object properties as they can be inferred.
from ow.
Or exactShape?
When you only see .shape()
in some code, is it clear enough that it allows additional properties? For me, it's not. How about partialShape()
or looseShape()
? I prefer the former. Open to other naming suggestions.
from ow.
I agree that this would be useful, though I'm not sure I'm in favor of adding it to the core API since unlike its usage in PropTypes
, you can accomplish the same thing with multiple ow
statements.
ow(input, ow.object)
ow(input.color, ow.string)
ow(input.height, ow.number.greatherThan(10))
This isn't possible with PropTypes
which is one reason they added PropTypes.shape
.
My main argument against it would be to keep the API surface as small as possible, but I do find myself using this pattern quite often especially for validating configuration parameters opts
.
Take this concrete example where I'm using ow for this purpose. It'd be really awkward if I tried to use a combination of ow.object.shape
and the upcoming optional
predicate to achieve what is more clearly defined by multiple ow
statements.
I could go either way, though, since I'm sure there are use cases where it'll still be useful to peeps. Just my 2 cents
from ow.
PropTypes.shape()
doesn't throw on additional unspecified keys. They have PropTypes.exact()
for that. We need to handle both cases.
from ow.
Exact should mean "exact" in that the shape should have all the same properties as the input object.
from ow.
Should both of these checks fail
Yes
from ow.
We also wouldn't need label() for the object properties as they can be inferred.
Sounds good to me :)
from ow.
We discussed this somewhere else, can't find it though. I believe our initial suggestion was just
ow(target, {
width: ow.number.positive.integer,
height: ow.number.positive.integer,
data: ow.any(ow.uint8Array, ow.uint8ClampedArray)
})
So just passing an object as second parameter would do the trick. I see positive sides to both ideas.
from ow.
@SamVerschueren I like that shorthand, but there's no way to use a label or to make it optional (when that is added) with that...
from ow.
Just a note; the shape
vs exact
semantics seem very related to the optional
operator and may have some overlap in implementation.
from ow.
@transitive-bullshit The optional
operator would only be useful for known optional properties. What about unknown properties?
from ow.
@issuehuntfest has funded $60.00 to this issue. See it on IssueHunt
from ow.
Using this for simple input validation, unfortunately only throws on the first error, but that's all I need to make sure there are no erroneous inputs being passed.
const matchShape = (source, shape) =>
new Promise((resolve, reject) => {
for (let key of Object.keys(source)) {
try {
ow(source[key], shape[key]);
} catch (e) {
return reject(e);
}
}
resolve();
});
Usage:
const obj = {
id: "Gozxoqqy79"
}
await matchShape(obj, {
id: ow.string
}).catch(e => {
console.log(e);
});
from ow.
This is a nice wrapper @mhaagens 😄 Any reason it has to be asynchronous?
from ow.
Thanks! :) Doesn't have to be at all. Just like to be explicit about returning a promise when using async/await and I like the syntax better than callbacks :).
from ow.
@mhaagens I meant that there's no need to use async / Promise or callbacks in this case since everything's synchronous.
const matchShape = (source, shape) => {
for (const key of Object.keys(source)) {
ow(source[key], shape[key]);
}
}
matchShape(obj, { id: ow.string })
from ow.
@transitive-bullshit Ah, yeah you're right!
from ow.
I want to start working on this. But before I do, what API are we going to use now?
// Allows extra properties
ow(target, ow.object.shape({
width: ow.number.positive.integer,
height: ow.number.positive.integer,
data: ow.any(ow.uint8Array, ow.uint8ClampedArray)
}));
And
// Doesn't allow extra properties
ow(target, ow.object.exact({
width: ow.number.positive.integer,
height: ow.number.positive.integer,
data: ow.any(ow.uint8Array, ow.uint8ClampedArray)
}));
Or
exactShape
?
from ow.
The partialShape
is already done exactShape
, I wasn't sure how it should handle certain use cases.
Does exactShape
mean it should be exact in both directions?
ow({unicorn: '🦄'}, ow.object.exactShape({
unicorn: ow.string,
rainbow: ow.string
}));
ow({unicorn: '🦄', rainbow: '🌈'}, ow.object.exactShape({
unicorn: ow.string
}));
Should both of these checks fail, or only one of them? It has quite some impact on the implementation.
from ow.
@sindresorhus has rewarded $54.00 to @SamVerschueren. See it on IssueHunt
💰 Total deposit: $60.00🎉 Repository reward(0%): $0.00- 🔧 Service fee(10%): $6.00
from ow.
Related Issues (20)
- Bug: `isValid` wrong typing HOT 3
- Package does not seem to work on node v8 `SyntaxError: Unexpected token {` HOT 1
- string.nonBlank validator HOT 1
- Error running with metro bundler
- generate objects from predicate HOT 3
- use browser-side HOT 1
- Unclear error message when checking NaN against the number type HOT 7
- Composition HOT 3
- Is there a way for an object predicate to differentiate between key with value `undefined`, and key not present? HOT 2
- should `ow.string.equals` be narrowing the type to specific strings? HOT 1
- wrong message: Expected `e` to be of type .... - instead of Expected argument to be of type HOT 3
- Show all possible errors exhaustively (option?)
- const values HOT 1
- Q: how to make custom type narrowing validator (i.e. Predicate<x>)? HOT 3
- metadata
- Documentation is 404
- Build errors when using ow in React app compiled with vite
- Upgrading to 1.1.0 from older version makes TS complain HOT 6
- correct pattern for optional 'required' properties?
- Cannot find module 'ow' or its corresponding type declarations HOT 6
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ow.