你能在运行时检查一个对象是否符合 Flow 类型吗?

Som*_*Guy 7 javascript unit-testing flowtype

我有一个正在解析的 JSON 对象,我正在为输出编写测试,但我无法在运行时检查特定对象是否符合流类型。

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?
        })
    });
});
Run Code Online (Sandbox Code Playgroud)

有什么办法可以实现吗?

Jar*_*ith 4

如果你的意思是在运行时使用flow,答案肯定是否定的,flow是用ocaml编写的。祝你好运,从 JavaScript 调用它。如果您的意思是验证对象属性的类型,那么大多数情况下答案是肯定的。您必须手动检查字段的类型。我会从这样的事情开始:

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

确保对象具有正确的键。

然后您必须检查这些键的值的类型是否正确。对于内置函数来说,这很简单:

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
Run Code Online (Sandbox Code Playgroud)

等等。对于通过构造函数创建的您自己的类型,new我将使用:

const _instanceOf = (ctor, obj) => {
  return (obj instanceof ctor) || 
   (ctor.name && ctor.name === obj.constructor.name);
};
Run Code Online (Sandbox Code Playgroud)

尽管这并非完全万无一失,但它应该足够有效。为了一点无耻的自我推销,我写了一个小库来处理很多这类东西,可以在这里找到它。也在npm上。