Skip to content

Excessively large type for maxItems #372

Closed
@Nevon

Description

@Nevon

Given a property such as:

{
  "type": "array",
  "minItems": 0,
  "maxItems": 1000,
  "items": {
    "type": "string",
    "anyOf": [
      {
        "$ref": "#/definitions/ipv4CidrBlockpattern"
      }
    ],
    "not": {
      "enum": [
        "0.0.0.0/0"
      ]
    }
  }
}

The generated type will be:

type ips = []
  | [Ipv4CidrBlockpattern & string]
  | [Ipv4CidrBlockpattern & string, Ipv4CidrBlockpattern & string]
  | [Ipv4CidrBlockpattern & string, Ipv4CidrBlockpattern & string, Ipv4CidrBlockpattern & string]
# ... and so on for each possible length of the array

Given a maxItems of 1000, the type definition becomes truly massive, and even fails to be generated in some cases.

Given a TupleOf type (from here) we could shrink this down quite a bit:

type BuildPowersOf2LengthArrays<N extends number, R extends never[][]> =
  R[0][N] extends never ? R : BuildPowersOf2LengthArrays<N, [[...R[0], ...R[0]], ...R]>;

type ConcatLargestUntilDone<N extends number, R extends never[][], B extends never[]> =
  B["length"] extends N ? B : [...R[0], ...B][N] extends never
    ? ConcatLargestUntilDone<N, R extends [R[0], ...infer U] ? U extends never[][] ? U : never : never, B>
    : ConcatLargestUntilDone<N, R extends [R[0], ...infer U] ? U extends never[][] ? U : never : never, [...R[0], ...B]>;

type Replace<R extends any[], T> = { [K in keyof R]: T }

type TupleOf<T, N extends number> = number extends N ? T[] : {
  [K in N]: 
  BuildPowersOf2LengthArrays<K, [[never]]> extends infer U ? U extends never[][]
  ? Replace<ConcatLargestUntilDone<K, U, []>, T> : never : never;
}[N];

type ips = Tuple<Ipv4CidrBlockpattern & string, 0>
  | TupleOf<Ipv4CidrBlockpattern & string, 1>
  | TupleOf<Ipv4CidrBlockpattern & string, 2>

This will still generate 1000 tuples in the union, but each tuple will only contain the parameter type once, rather than N times.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions