Search code examples
node.jstypescriptexpressjsonschemaajv

ajv array with union types


Suppose I have the following type:

type MixedArray = Array<number | string>;

And sample data that I'd like to be valid:

[ 'dfdf', 9, 0, 'sdfdsf' ]

How do I create an ajv JSONSchemeType that will validate the expected mixed array?

I have tried the following:

import { JSONSchemaType } from 'ajv';

const Mixed: JSONSchemaType<MixedArray> = {
    type: 'array',
    items: {
        anyOf: [
            { type: 'number' },
            { type: 'string' },
        ]
    }

};

But I receive a typescript error:

Type '{ anyOf: ({ type: "number"; } | { type: "string"; })[]; }' is not assignable to type 'JSONSchemaType<string | number, false>'.

json-schema.d.ts(34, 5): The expected type comes from property 'items' which is declared here on type 'JSONSchemaType<MixedType, false>'


Solution

  • Since I posted my question, I now try to avoid writing union types when possible. For simplicity sake.

    But in the example situation (or others where the union can be an advantage), I discovered that you can wish away the type error by typing the union with any and the schema will still work as expected (so long as your functions that depend on the schema know that it is a union type, of course):

    import { JSONSchemaType } from 'ajv';
    
    const Mixed: JSONSchemaType<MixedArray> = {
        type: 'array',
        items: {
            anyOf: [
                { type: 'number' },
                { type: 'string' },
            ]
        }
    
    } as any; // <----- add type declaration here
    
    

    The disadvantage of this approach is that your schema is not strongly typed. To that end, I suppose you could extend JSONSchemaType to strengthen your definition.