admin管理员组

文章数量:1279043

I have a JSON object that is being parsed, and I'm writing tests for the output and I wan't to be able to check if a specific object conforms to a flow type, at runtime.

const object = {/**/}

type SomeType = {
    foo: string,
    bar: bool,
    baz: Object,
}

describe('object', () => {
    describe('.subfield', () => {
        it('conforms to SomeType', () => {
            // Here I want to write an 'expect'
            // that checks if object.subfield
            // conforms to the SomeType flow type?
        })
    });
});

Is there any way this is achievable?

I have a JSON object that is being parsed, and I'm writing tests for the output and I wan't to be able to check if a specific object conforms to a flow type, at runtime.

const object = {/**/}

type SomeType = {
    foo: string,
    bar: bool,
    baz: Object,
}

describe('object', () => {
    describe('.subfield', () => {
        it('conforms to SomeType', () => {
            // Here I want to write an 'expect'
            // that checks if object.subfield
            // conforms to the SomeType flow type?
        })
    });
});

Is there any way this is achievable?

Share Improve this question edited Mar 28, 2017 at 20:54 Nat Mote 4,08619 silver badges30 bronze badges asked Aug 3, 2016 at 12:52 SomeNorwegianGuySomeNorwegianGuy 1,5345 gold badges18 silver badges45 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 4

If you mean use flow at runtime, the answer is definitively no, flow is written in ocaml. Good luck calling that from JavaScript. If you mean verify the types of the properties of an object, the answer is, for the most part, yes. You will have to manually check the types of the fields. I would start with something like this:

let expectedKeys = ['foo', 'bar', 'baz'].sort().toString();
expect(Object.keys(testObj).sort().toString()).toBe(expectedKeys);

To make sure the object has the proper keys.

Then you will have to check if the types of the values at those keys are correct. For built-ins, this is easy:

const _extractHiddenClass = (r => a => {
  return Object.prototype.toString.call(a).match(r)[1].toLowerCase();
})(/ ([a-z]+)]$/i);

_extractHiddenClass(/inrst/i); // regexp
_extractHiddenClass(true);     // boolean
_extractHiddenClass(null);     // null

And so on. For your own types made via a constructor with new I'd use:

const _instanceOf = (ctor, obj) => {
  return (obj instanceof ctor) || 
   (ctor.name && ctor.name === obj.constructor.name);
};

Although this isn't totally foolproof, it should work well enough. And for a bit of shameless self-promotion, I wrote a little library that handles a lot of this kind of stuff, find it here. Also on npm.

Check https://codemix.github.io/flow-runtime Flow-patible runtime type system for JavaScript.

The runtime-types project looks promising.

From the README,

example-types.js

// @flow
export type PhoneNumber = string;

export type User = {
  username: string;
  age: number;
  phone: PhoneNumber;
  created: ?Date;
}

validator.js

var types = require('runtime-types')
var validate = require('runtime-types').validate

var MyTypes = types.readFile(path.join(__dirname, '../test/example-types.js'))

var VALIDATORS = {
  PhoneNumber: validate.validateRegex(/^\d{10}$/),
}

var validators = validate.createAll(VALIDATORS, MyTypes)

var errs = validators.User({
  age: 23,
  phone: "8014114399"
})

// ==> [ { key: 'username', value: undefined, error: 'missing' } ]

I don't know why people do not use it more, but joi is a fantastic shape and type validation library

You can define any object shape and then just check which objects conforms. If you want an assertion like experience you can do it like this

const schema = joi.object().keys({a:joi.string()});
joi.assert(myObj,schema,"error message") 

本文标签: javascriptCan you check if an object conforms to a Flow type at runtimeStack Overflow