ajv-validator / ajv-validator/ajv

Conditional type + union + generics not allowed

Aperta
#2,172 0 commenti 1 reazione 0 assegnatari Vedi su GitHub
limitation typescript
Lingua principale
TypeScript
Stelle
14.8k
Fork
1k
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Descrizione

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

**Ajv options object**
Using these:
```
import ajvErrors from 'ajv-errors'
import addFormats from 'ajv-formats'
import betterAjvErrors from 'better-ajv-errors'
```

default options.

**Problem**

I want to have a type definition like

```typescript
type Test2 = T extends undefined ? undefined : JSONSchemaType
```

However, this fails for types where `T` is a union type. Here is a complete example highlighting the problem:

```typescript
import { JSONSchemaType } from 'ajv'

type ExampleStringBody = {
foo: string
}

type ExampleNumberBody = {
bar: number
}

type ExampleBody = ExampleStringBody | ExampleNumberBody

const exampleNumberBodySchema: JSONSchemaType = {
type: 'object',
required: ['bar'],
properties: {
bar: {
type: 'number',
},
},
}

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

const exampleBodySchema: JSONSchemaType = {
type: 'object',
oneOf: [exampleNumberBodySchema, exampleStringBodySchema],
}

// This one does not work. The rest of the example below this one work.
// ✕ | ✓ conditional type | ✓ union | ✓ generic
type Type1 = T extends undefined ? undefined : JSONSchemaType
const a: Type1 = exampleBodySchema

// ✓ | ✓ conditional type | ✕ union | ✓ generic
const b: Type1 = exampleStringBodySchema

// ✓ | ✕ conditional type | ✓ union | ✓ generic
type Type2 = JSONSchemaType
const c: Type2 = exampleBodySchema

// ✓ | ✓ conditional type | ✓ union | ✕ generic
type Test1 = ExampleBody extends undefined
? undefined
: JSONSchemaType
const d: Test1 = exampleBodySchema

// ✓ | ✕ conditional type | ✕ union | ✓ generic
const e: Type2 = exampleBodySchema

// ✓ | ✓ conditional type | ✕ union | ✕ generic
type Type3 = ExampleStringBody extends undefined
? undefined
: JSONSchemaType
const f: Type3 = exampleStringBodySchema
```

For whatever reason, the specific combination of generics + union + generics is not accepted by typescript. The error I get out is:

```
const a: UncheckedJSONSchemaType | UncheckedJSONSchemaType

Type '{ oneOf: readonly UncheckedJSONSchemaType[]; } & { [keyword: string]: any; $id?: string | undefined; $ref?: string | undefined; $defs?: Record<...> | undefined; definitions?: Record<...> | undefined; }' is not assignable to type 'UncheckedJSONSchemaType | UncheckedJSONSchemaType'.
Type '{ oneOf: readonly UncheckedJSONSchemaType[]; } & { [keyword: string]: any; $id?: string | undefined; $ref?: string | undefined; $defs?: Record<...> | undefined; definitions?: Record<...> | undefined; }' is not assignable to type '{ type: "object"; additionalProperties?: boolean | UncheckedJSONSchemaType | undefined; unevaluatedProperties?: boolean | UncheckedJSONSchemaType | undefined; ... 7 more ...; maxProperties?: number | undefined; } & { ...; } & { ...; } & { ...; }'.
Property 'type' is missing in type '{ oneOf: readonly UncheckedJSONSchemaType[]; } & { [keyword: string]: any; $id?: string | undefined; $ref?: string | undefined; $defs?: Record<...> | undefined; definitions?: Record<...> | undefined; }' but required in type '{ type: "object"; additionalProperties?: boolean | UncheckedJSONSchemaType | undefined; unevaluatedProperties?: boolean | UncheckedJSONSchemaType | undefined; ... 7 more ...; maxProperties?: number | undefined; }'.ts(2322)
json-schema.d.ts(57, 5): 'type' is declared here.
```

I've ready all of the threads on union types in here that I can find.

Guida per i contributori

Apri la guida per i contributori

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.