ajv-validator / ajv-validator/ajv-errors
`JSONSchemaType` + `anyOf` corresponding to union over objects cannot correctly determine missing fields
- Ngôn ngữ chính
- TypeScript
- Star
- 289
- Fork
- 21
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Mô tả
## 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
```
Hướng dẫn đóng góp
Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này
Đánh giá
Issue này chưa được đánh giá.