ajv-validator / ajv-validator/ajv

JSONSchemaType does not correctly handle nullable fields when referenced using $ref

未關閉
#2,223 8 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視
limitation typescript
主要語言
TypeScript
星號
14.8k
分支
1k
PR 合併指標
30 天內沒有已合併 PR

描述

**What version of Ajv are you using? Does the issue happen if you use the latest version?**
latest, yes

**Ajv options object**
{}

```javascript
import {JSONSchemaType} from "ajv"

interface Foo {
foo?: string;
}

const FooSchema: JSONSchemaType = {
type: 'object',
properties: {
foo: {
type: 'string',
nullable: true
}
},
required: []
}

interface Bar {
bar: Foo
}

const BarSchema: JSONSchemaType = {
type: 'object',
properties: {
bar: {
type: 'object',
$ref: '#/definitions/Foo'
}
},
required: [],
definitions: {
Foo: FooSchema
}
}

console.log(FooSchema, BarSchema)
```

**Sample data**
NA

**Your code**
See above, also a [TS Playground](https://www.typescriptlang.org/play?ts=4.7.2#code/JYWwDg9gTgLgBAbwFIGUDyA5FBjAFgUxAEMAVATzHwF84AzKCEOAIiICsA3ZgKG+ADsY+KLSLZ8cAGIQIibnDoyA-AC44AZxhQBAcwDc3Kr2wR+mqTJwFia1JiuFSFfAB5pEAHxwAvHIUxnNQByCAAjNnxsGCCAGnk4MAZKWGB8dTUEeIVaGQyshTgAymDNbX4dWPyFfgBXABs6olC6-DUtGvx8owUqOIUofABHGuABgBM1AG0AXUNeASERMQkAISIoPzhQ9bV3Oe4TM3g1qAcbODssPEdyShcTr19M-0C4EPDI6L6EpOEYVPSmwU2ygeQKBSKrTeYQiUUq4IUABIBrRggBiAD0Y3wtAEwH+pnUGPcQS68V68QGw1G+AmcBm32xuP4+OAhLBBXcu0s12I5P2h3UEBaADo6hAdAAKdxnIgxOAnWUASm4QA)
**Validation result, data AFTER validation, error messages**

```
Type '{ type: "object"; additionalProperties?: boolean | UncheckedJSONSchemaType | undefined; unevaluatedProperties?: boolean | UncheckedJSONSchemaType | undefined; ... 7 more ...; maxProperties?: number | undefined; } & { ...; } & { ...; } & { ...; }' is not assignable to type 'UncheckedJSONSchemaType'.
Type '{ type: "object"; additionalProperties?: boolean | UncheckedJSONSchemaType | undefined; unevaluatedProperties?: boolean | UncheckedJSONSchemaType | undefined; ... 7 more ...; maxProperties?: number | undefined; } & { ...; } & { ...; } & { ...; }' is not assignable to type '{ type: "object" | undefined; additionalProperties?: boolean | UncheckedJSONSchemaType | undefined; unevaluatedProperties?: boolean | ... 1 more ... | undefined; ... 7 more ...; maxProperties?: number | undefined; } & { ...; } & { ...; } & { ...; }'.
Type '{ type: "object"; additionalProperties?: boolean | UncheckedJSONSchemaType | undefined; unevaluatedProperties?: boolean | UncheckedJSONSchemaType | undefined; ... 7 more ...; maxProperties?: number | undefined; } & { ...; } & { ...; } & { ...; }' is not assignable to type '{ type: "object" | undefined; additionalProperties?: boolean | UncheckedJSONSchemaType | undefined; unevaluatedProperties?: boolean | UncheckedJSONSchemaType<...> | undefined; ... 7 more ...; maxProperties?: number | undefined; }'.
Types of property 'properties' are incompatible.
Type 'UncheckedPropertiesSchema | undefined' is not assignable to type 'Partial> | undefined'.
Type 'UncheckedPropertiesSchema' is not assignable to type 'Partial>'.
Property 'foo' is incompatible with index signature.
Type '{ $ref: string; } | (UncheckedJSONSchemaType & { nullable: true; const?: null | undefined; enum?: readonly (string | null | undefined)[] | undefined; default?: string | ... 1 more ... | undefined; })' is not assignable to type '{ $ref: string; } | ({ anyOf: readonly UncheckedJSONSchemaType[]; } & { [keyword: string]: any; $id?: string | undefined; $ref?: string | undefined; $defs?: Record<...> | undefined; definitions?: Record<...> | undefined; } & { ...; }) | ... 9 more ... | undefined'.
Type '{ anyOf: readonly UncheckedJSONSchemaType[]; } & { [keyword: string]: any; $id?: string | undefined; $ref?: string | undefined; $defs?: Record<...> | undefined; definitions?: Record<...> | undefined; } & { ...; }' is not assignable to type '{ $ref: string; } | ({ anyOf: readonly UncheckedJSONSchemaType[]; } & { [keyword: string]: any; $id?: string | undefined; $ref?: string | undefined; $defs?: Record<...> | undefined; definitions?: Record<...> | undefined; } & { ...; }) | ... 9 more ... | undefined'.
Type '{ anyOf: readonly UncheckedJSONSchemaType[]; } & { [keyword: string]: any; $id?: string | undefined; $ref?: string | undefined; $defs?: Record<...> | undefined; definitions?: Record<...> | undefined; } & { ...; }' is not assignable to type '{ $ref: string; }'.
Types of property '$ref' are incompatible.
Type 'string | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'.
```

For some reason, typescript/ajv cannot handle nullable fields in nested schemas. The above example is a minimum repro where Foo has a nullable field, and is then referenced inside Bar.

If I remove the nullable field, i.e.
```
interface Foo {
foo: string
}
```
and adjust the schema accordingly, everything compiles.

**What results did you expect?**
No compilation issues

**Are you going to resolve the issue?**

貢獻指南

開啟貢獻指南

評估

這個 Issue 還沒有評估資料。

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。