首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Joi.object()和Joi.object().keys()有什么区别?

Joi.object()和Joi.object().keys()有什么区别?
EN

Stack Overflow用户
提问于 2019-11-12 11:17:53
回答 4查看 13.3K关注 0票数 16

根据Joi文档,您可以像这样使用Joi.object()

代码语言:javascript
复制
const object = Joi.object({
    a: Joi.number().min(1).max(10).integer(),
    b: Joi.any()
});

但您也可以使用Joi.object().keys()编写等效的代码,如下所示:

代码语言:javascript
复制
const object = Joi.object().keys({
    a: Joi.number().min(1).max(10).integer(),
    b: Joi.any()
});

这两者有什么不同?

EN

回答 4

Stack Overflow用户

发布于 2020-06-24 07:51:48

如果只编写一次模式,则不需要使用.keys()。正如他们的文档所说,当向对象添加更多行(键)时,使用.keys()是“有用的”。

Joi.object().keys([schema]) notation

这与Joi.object([schema])基本相同,但当您想要添加更多密钥(例如多次调用keys() )时,使用Joi.object().keys([schema])更有用。如果您只添加一组密钥,则可以跳过keys()方法,直接使用object()

有些人喜欢使用keys()来使代码更明确(这只是样式)。

摘自:https://github.com/hapijs/joi/blob/v8.0.3/API.md#joiobjectkeysschema-notation

我还发现了这个:

的用法有很多种。hapi文档不能显示所有内容。只有在将键添加到对象时,才建议调用key(),因为它会创建另一个架构

摘自:https://github.com/hapijs/hapi/issues/2222

票数 7
EN

Stack Overflow用户

发布于 2020-03-09 22:30:30

@hapi/joi documentation对此不是很清楚(在v17.1.0)。得到的模式具有相同的值,并且它们验证相同的值。从源代码上看,Object类型是一个Keys类型,只有一个变化,对象不需要从任何定义它的类型中复制keys。

代码语言:javascript
复制
Welcome to Node.js v12.16.1.
Type ".help" for more information.
> const Joi = require('@hapi/joi')
undefined
> const util = require('util')
undefined
> const object1 = Joi.object({
...     a: Joi.number().min(1).max(10).integer(),
...     b: Joi.any()
... });
undefined
> const object2 = Joi.object().keys({
...     a: Joi.number().min(1).max(10).integer(),
...     b: Joi.any()
... });
undefined
> util.format(object1) == util.format(object2)
true
> object1.validate({a: 1, b: 1})
{ value: { a: 1, b: 1 } }
> object2.validate({a: 1, b: 1})
{ value: { a: 1, b: 1 } }
> object1.validate({a: 0})
{
value: { a: 0 },
error: [Error [ValidationError]: "a" must be larger than or equal to 1] {
    _original: { a: 0 },
    details: [ [Object] ]
}
}
> object2.validate({a: 0})
{
value: { a: 0 },
error: [Error [ValidationError]: "a" must be larger than or equal to 1] {
    _original: { a: 0 },
    details: [ [Object] ]
}
}
> object1.validate({a: 1, b: 1, c:1})
{
value: { a: 1, b: 1, c: 1 },
error: [Error [ValidationError]: "c" is not allowed] {
    _original: { a: 1, b: 1, c: 1 },
    details: [ [Object] ]
}
}
> object2.validate({a: 1, b: 1, c:1})
{
value: { a: 1, b: 1, c: 1 },
error: [Error [ValidationError]: "c" is not allowed] {
    _original: { a: 1, b: 1, c: 1 },
    details: [ [Object] ]
}
}
> object1.validate({a: 1})
{ value: { a: 1 } }
> object2.validate({a: 1})
{ value: { a: 1 } }
> object1.validate({b: 1})
{ value: { b: 1 } }
> object2.validate({b: 1})
{ value: { b: 1 } }
> object1.validate({})
{ value: {} }
> object2.validate({})
{ value: {} }

.append(schema).keys(schema)之间的区别在文档中也不清楚。如果schema为空,则.append(schema)不会创建新的副本,否则它只返回来自.keys(schema)的值。我找不到这样做会有所不同的例子。

代码语言:javascript
复制
> util.format(Joi.object({}).keys({a:1})) == util.format(Joi.object({}).append({a:1}))
true
> util.format(Joi.object({}).unknown().keys({a:1})) == util.format(Joi.object({}).unknown().append({a:1}))
true
票数 3
EN

Stack Overflow用户

发布于 2020-07-31 18:08:45

object.keys(schema)

设置或扩展允许的对象键,其中:

  • 模式-可选对象,其中每个键都被分配一个joi类型的对象。如果schema为{},则不允许使用键。如果schema为null或未定义,则允许任何键。如果架构是具有键的对象,则键被添加到以前定义的任何键中(但如果以前允许所有键,则缩小选择范围)。

因此,通过调用Joi.object(),您首先创建了一个允许任何键的模式,然后通过调用.keys([schema]),您可以对该模式进行扩展(基本上与使用Joi.object([schema])定义新模式相同)。

所以这两个是等价的:

代码语言:javascript
复制
const a = Joi.object({ firstName: Joi.string() });
const b = Joi.object().keys({ firstName: Joi.string() });

代码语言:javascript
复制
const aExtended = a.keys({ lastName: Joi.string() })
const bExtended = b.keys({ lastName: Joi.string() })

那该用哪一个呢?

就像在前面的答案中所说的,有时出于代码一致性的原因,顶级模式也是使用.keys()创建的,但最终我认为这是个人喜好的问题。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58811509

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档