diff --git a/sandbox-app/simple-array.tsx b/sandbox-app/simple-array.tsx index f6aa3c0..ca58fde 100644 --- a/sandbox-app/simple-array.tsx +++ b/sandbox-app/simple-array.tsx @@ -6,9 +6,7 @@ interface Model { emails?: string[]; } -const initialValue: Model = { - emails: ['bye@example.com', 'stay@example.com'], -}; +const initialValue: Model = {}; export function SimpleArray(): JSX.Element { const { diff --git a/src/field.ts b/src/field.ts index 8a75423..d23c3e5 100644 --- a/src/field.ts +++ b/src/field.ts @@ -5,8 +5,8 @@ import { MappedValidation, validateValue } from './validation'; for each field. In this case, for each field of T, string | number you get back a FormField type */ export type MappedFields = { - [P in keyof Required]: T[P] extends unknown[] - ? FieldSet + [P in keyof Required]: T[P] extends unknown[] | undefined + ? FieldSet[0]> : T[P] extends Record | undefined | null ? NestedField> : Field; @@ -127,6 +127,10 @@ export class FieldImplementation } add(element: T): void { + if (!this.value) { + this.value = [] as unknown as T; + } + this.value = [ ...(this.value as unknown as unknown[]), element, @@ -224,9 +228,12 @@ export class FieldImplementation #createSubfields(): void { const value = this.value; if (Array.isArray(value)) { - this.elements = value.map((e, index) => - this.createFieldSetField(e, this.#originalValue[index]) - ); + this.elements = value.map((e, index) => { + if (this.#originalValue === undefined) { + return this.createFieldSetField(e, e); + } + return this.createFieldSetField(e, this.#originalValue[index]); + }); } else { // make sure as many fields as possible are initialized if (this.isNestedValidation) { diff --git a/src/form.spec.ts b/src/form.spec.ts index b769e10..cdb352e 100644 --- a/src/form.spec.ts +++ b/src/form.spec.ts @@ -28,7 +28,7 @@ interface Model { age: number; description?: string; nullableValue: string | null; - emails: string[]; + emails?: string[]; address?: { streetName?: string; streetNumber?: number; @@ -43,7 +43,6 @@ const defaultValue: Model = { name: '', age: 18, nullableValue: null, - emails: [], hobbies: [], }; @@ -253,7 +252,7 @@ describe(Form, () => { const form = createForm({ validations: { emails: ({ model }) => - model.emails.length === 0 ? ['specify at least one'] : [], + (model.emails ?? []).length === 0 ? ['specify at least one'] : [], }, }); expect(form.fields.emails.errors).toEqual(['specify at least one']); @@ -476,18 +475,14 @@ describe(Form, () => { describe('fields array', () => { describe('creating', () => { it('creates empty array', () => { - const form = createForm({ - value: { emails: [] }, - }); + const form = createForm(); const emails = form.fields.emails; expect(emails.elements).toBeDefined(); expect(Array.isArray(emails.elements)).toEqual(true); expect(emails.elements.length).toEqual(0); }); it('adds a new field', () => { - const form = createForm({ - value: { emails: [] }, - }); + const form = createForm(); const emails = form.fields.emails; emails.add('test'); expect(emails.value.length).toEqual(1);