From 4d2279f74c361c45e27f461989a0b9e90b6d4d16 Mon Sep 17 00:00:00 2001 From: Nicolas Froidure Date: Mon, 9 Oct 2023 14:09:43 +0200 Subject: [PATCH] feat(types): encode min length arrays into types Allows to encode into produced types the minnimum length of arrays. --- src/index.test.ts | 27 +++++++++++++++++++++++++++ src/index.ts | 25 +++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/src/index.test.ts b/src/index.test.ts index 110679d..0c203dc 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -1074,6 +1074,33 @@ describe('generateTypeDeclaration()', () => { `); }); + test('should create tuples from min length arrays', async () => { + const schema: JSONSchema7 = { + title: 'FixedArrayToTupleTest', + type: 'object', + additionalProperties: false, + required: ['data'], + properties: { + data: { + type: 'array', + items: { type: 'string' }, + minItems: 2, + }, + }, + }; + + expect(toSource(await generateTypeDeclaration(context, schema))) + .toMatchInlineSnapshot(` +"export type FixedArrayToTupleTest = NonNullable<{ + data: NonNullable<[ + NonNullable, + NonNullable, + ...NonNullable[] + ]>; +}>;" +`); + }); + test('should work with tuples and rest test case schemas', async () => { const schema: JSONSchema7 = { title: 'TupleTest', diff --git a/src/index.ts b/src/index.ts index 4286344..4b5d13f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1312,6 +1312,31 @@ async function buildArrayTypeNode( ); } + // Switch from arrays to tuples and spread for small min length arrays + if ( + 'minItems' in schema && + typeof schema.minItems === 'number' && + schema.minItems > 0 && + schema.minItems < + context.jsonSchemaOptions.tuplesFromFixedArraysLengthLimit + ) { + return ts.factory.createTupleTypeNode( + new Array(schema.minItems) + .fill( + types.length > 1 ? ts.factory.createUnionTypeNode(types) : types[0], + ) + .concat( + ts.factory.createRestTypeNode( + ts.factory.createArrayTypeNode( + types.length > 1 + ? ts.factory.createUnionTypeNode(types) + : types[0], + ), + ), + ), + ); + } + return ts.factory.createArrayTypeNode( types.length > 1 ? ts.factory.createUnionTypeNode(types) : types[0], );