你能在运行时检查一个对象是否符合 Flow 类型吗?
Can you check if an object conforms to a Flow type at runtime?
我有一个正在解析的 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?
})
});
});
有什么方法可以实现吗?
如果你的意思是在运行时使用流,答案肯定是否定的,流是用ocaml写的。祝你从 JavaScript 调用它好运。如果您的意思是验证对象属性的类型,那么答案在很大程度上是肯定的。您将必须手动检查字段的类型。我会从这样的事情开始:
let expectedKeys = ['foo', 'bar', 'baz'].sort().toString();
expect(Object.keys(testObj).sort().toString()).toBe(expectedKeys);
确保对象具有正确的键。
然后你将不得不检查这些键值的类型是否正确。对于内置插件,这很简单:
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
等等。对于通过带有 new
的构造函数创建的您自己的类型,我将使用:
const _instanceOf = (ctor, obj) => {
return (obj instanceof ctor) ||
(ctor.name && ctor.name === obj.constructor.name);
};
尽管这并非万无一失,但应该可以正常工作。为了有点无耻的自我推销,我写了一个小库来处理很多这类东西,找到它 here. Also on npm。
runtime-types project 看起来很有希望。
来自自述文件,
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' } ]
我不知道为什么人们不经常使用它,但是 joi 是一个很棒的形状和类型验证库
您可以定义任何对象形状,然后只需检查哪些对象符合。如果你想要像体验这样的断言,你可以这样做
const schema = joi.object().keys({a:joi.string()});
joi.assert(myObj,schema,"error message")
检查 https://codemix.github.io/flow-runtime JavaScript 的流兼容运行时类型系统。
我有一个正在解析的 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?
})
});
});
有什么方法可以实现吗?
如果你的意思是在运行时使用流,答案肯定是否定的,流是用ocaml写的。祝你从 JavaScript 调用它好运。如果您的意思是验证对象属性的类型,那么答案在很大程度上是肯定的。您将必须手动检查字段的类型。我会从这样的事情开始:
let expectedKeys = ['foo', 'bar', 'baz'].sort().toString();
expect(Object.keys(testObj).sort().toString()).toBe(expectedKeys);
确保对象具有正确的键。
然后你将不得不检查这些键值的类型是否正确。对于内置插件,这很简单:
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
等等。对于通过带有 new
的构造函数创建的您自己的类型,我将使用:
const _instanceOf = (ctor, obj) => {
return (obj instanceof ctor) ||
(ctor.name && ctor.name === obj.constructor.name);
};
尽管这并非万无一失,但应该可以正常工作。为了有点无耻的自我推销,我写了一个小库来处理很多这类东西,找到它 here. Also on npm。
runtime-types project 看起来很有希望。
来自自述文件,
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' } ]
我不知道为什么人们不经常使用它,但是 joi 是一个很棒的形状和类型验证库
您可以定义任何对象形状,然后只需检查哪些对象符合。如果你想要像体验这样的断言,你可以这样做
const schema = joi.object().keys({a:joi.string()});
joi.assert(myObj,schema,"error message")
检查 https://codemix.github.io/flow-runtime JavaScript 的流兼容运行时类型系统。