ajv-validator / ajv-validator/ajv-errors

`JSONSchemaType` + `anyOf` corresponding to union over objects cannot correctly determine missing fields

Aberta
#144 2 comentários 2 reações 0 responsáveis Ver no GitHub
Linguagem predominante
TypeScript
Estrelas
289
Forks
21
Métricas de merge de PRs
Nenhum PR com merge em 30d

Descrição

## Problem description
AJV cannot infer which subtype of a union is being used when creating a union over objects. This might be an issue with AJV core, or just an issue with the error handling.

Below is a simple but complete example of the issue:

```typescript
import ajvErrors from 'ajv-errors'
import addFormats from 'ajv-formats'
import Ajv, { JSONSchemaType } from 'ajv'

type UploadAction = {
actionType: 'UPLOAD'
url: string
filename: string
}

type EmailAction = {
actionType: 'EMAIL'
email: string
}

type Action = UploadAction | EmailAction
type Actions = Array

const schema: JSONSchemaType = {
type: 'array',
items: {
anyOf: [
{
type: 'object',
required: ['actionType', 'url', 'filename'],
properties: {
actionType: {
type: 'string',
const: 'UPLOAD',
},
url: {
type: 'string',
},
filename: {
type: 'string',
},
},
},
{
type: 'object',
required: ['actionType', 'email'],
properties: {
actionType: {
type: 'string',
const: 'EMAIL',
},
email: {
type: 'string',
},
},
},
],
},
}

if (require.main === module) {
const ajv = new Ajv({ allErrors: true })
ajvErrors(ajv)
addFormats(ajv)
const validate = ajv.compile(schema)

const data: Array = [
{
actionType: 'UPLOAD',
},
]

if (validate(data)) {
console.log(data)
} else {
console.log(validate.errors)
}
}
```

Run this using `ts-node` or compile and run it via node. The output I get is
```
[
{
instancePath: '/0',
schemaPath: '#/items/anyOf/0/required',
keyword: 'required',
params: { missingProperty: 'url' },
message: "must have required property 'url'"
},
{
instancePath: '/0',
schemaPath: '#/items/anyOf/0/required',
keyword: 'required',
params: { missingProperty: 'filename' },
message: "must have required property 'filename'"
},
{
instancePath: '/0',
schemaPath: '#/items/anyOf/1/required',
keyword: 'required',
params: { missingProperty: 'email' },
message: "must have required property 'email'"
},
{
instancePath: '/0/actionType',
schemaPath: '#/items/anyOf/1/properties/actionType/const',
keyword: 'const',
params: { allowedValue: 'EMAIL' },
message: 'must be equal to constant'
},
{
instancePath: '/0',
schemaPath: '#/items/anyOf',
keyword: 'anyOf',
params: {},
message: 'must match a schema in anyOf'
}
]
```

When I specify `actionType: 'UPLOAD'`, I expect that the only missing fields should `url` and `filename`. The errors output by AJV are confusing and misleading.

In contrast, the typescript type inference engine is correctly able to deduce the the missing fields once the `actionType` field is set to one of `EMAIL` or `UPLOAD`.

Here are my versions via `yarn list`:
```
├─ ajv-errors@3.0.0
├─ ajv-formats@2.1.1
│ └─ ajv@^8.0.0
├─ ajv@8.8.2
│ ├─ fast-deep-equal@^3.1.1
│ ├─ json-schema-traverse@^1.0.0
│ ├─ require-from-string@^2.0.2
│ └─ uri-js@^4.2.2
```

Guia de contribuição

Nenhum guia de contribuição indexado para este repositório

Avaliação

Esta issue ainda não foi avaliada.

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.