Is it possible to check if a JSON object validates against all properties of my class definition?
- Dominant language
- JavaScript
- Stars
- 797
- Forks
- 49
- PR merge metrics
- No merged PRs in 30d
Description
This is a:
- [ ] Bug Report
- [ ] Feature Request
- [X] Question
- [ ] Other
Which concerns:
- [X] flow-runtime
- [X] babel-plugin-flow-runtime
- [ ] flow-runtime-validators
- [ ] flow-runtime-mobx
- [ ] flow-config-parser
- [ ] The documentation website
---
### What is the current behaviour?
I'm banging my head against the wall for a couple of hours now (yes, it hurts!). I'm trying to implement a validation for JSON objects. I have a class like:
```js
import _ from "lodash";
class MySchema {
foo: string;
bar: string;
assign(payload: Object) {
_.assign(this, payload);
}
doSomething() { ... };
doSomethingElse() { ... };
}
```
In the `MySchema#assign` above I'm now trying to validate a plain object `payload = { foo: "foo", bar: "bar" }` against that class definition. I've tried a couple of different approaches without much success:
This code only checks that the payload is an instance of `MySchema`, but doesn't check the properties `foo` and `bar` for validity.
```js
const schemaValidator = (reify: Type< MySchema >);
schemaValidator.assert(_.assign(new MySchema(), payload));
```
There's little documentation but `$Shape` looked like something useful. Unfortunately the following code just throws an "Can only $Shape object types." exception:
```js
const schemaValidator = (reify: Type< $Shape< MySchema > >);
schemaValidator.assert(payload);
```
The validation works as expected if I change `MySchema` to a `type` instead of a `class`. But obviously that's not what I want as I'd like to provide additional functions (`#doSomething` and `#doSomethingElse`) in the class instance. There seems to be no way in Flow to have a class inherit from a Type.
Another way I found is to define `MySchema` as an interface instead of a class, but this makes me repeat all properties in the actual class implementation like this:
```js
interface MySchema {
foo: string;
bar: string;
}
class MyEntity implements MySchema {
foo: string; // <-- I have to duplicate all properties here
bar: string; // <-- yuck
doSomething() { ... };
doSomethingElse() { ... };
}
// But at least the validation seems to work now...
const schemaValidator = (reify: Type< MySchema >);
schemaValidator.assert(payload);
```
I had plenty of other iterations but can't get it to really work intuitively.
---
### What is the expected behaviour?
I would hope to find a simple way of validating that my JSON object is indeed "compatible" with my class definition. Is that possible?
---
### Which package versions are you using?
```
├── babel-plugin-flow-runtime@0.11.1
├── babel-preset-flow@6.23.0
├── eslint-plugin-flow-check@1.1.1
├── eslint-plugin-flowtype@2.35.1
├── flow-bin@0.54.1
├── flow-runtime@0.14.0
├── flow-typed@2.1.5
```
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.