ajv-validator / ajv-validator/ajv-errors

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

Abierto
#144 2 comentarios 2 reacciones 0 asignados Ver en GitHub
Lenguaje dominante
TypeScript
Estrellas
289
Forks
21
Métricas de merge de PR
Sin PR fusionados en 30 d

Descripción

## 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
```

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.