From 19e28d48c7006bc726e8eed653600918f5b36e35 Mon Sep 17 00:00:00 2001 From: Vladislav Date: Fri, 6 Dec 2024 00:39:02 +0200 Subject: [PATCH] Update readme.md add link to playground --- README.md | 6 +++- tests/misc.test.mts | 79 ++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 76 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index c0c165d..8a1bc73 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,10 @@ It doesn't increase your bundle size because it's just TypeScript types. +## Playground is here +You can play around using this link: +https://stackblitz.com/edit/ngx-mf-playground?file=src%2Fmain.ts + ## Installation npm @@ -365,4 +369,4 @@ Because if you use array syntax, then you can't pass argument to FormGroup type. * Stackoverflow questions - https://stackoverflow.com/questions/72500855/formbuilder-with-strongly-typed-form-in-ng14 https://stackoverflow.com/questions/72507263/angular-14-strictly-typed-reactive-forms-how-to-type-formgroup-model-using-exi * Dev.to article - https://dev.to/iamguid/new-way-to-cook-angular-14-typed-forms-1g7h * Medium article - https://medium.com/p/1ffebf193df -* Playground - \ No newline at end of file +* Playground - https://stackblitz.com/edit/ngx-mf-playground?file=src%2Fmain.ts \ No newline at end of file diff --git a/tests/misc.test.mts b/tests/misc.test.mts index 7d68509..1d07bc5 100644 --- a/tests/misc.test.mts +++ b/tests/misc.test.mts @@ -1,7 +1,7 @@ import "@angular/compiler" import { FormBuilder } from "@angular/forms"; -import { FormElementControl, FormElementGroup, FormType, G, T } from "../src/index.mjs"; +import { FormElementControl, FormElementGroup, FormType, G, I, T } from "../src/index.mjs"; describe('Misc tests', () => { it('undefined nullable optional field should be nonnullalbe', () => { @@ -133,7 +133,7 @@ describe('Misc tests', () => { it('additional field', () => { interface Model { a: number; - } + } const fb = new FormBuilder().nonNullable; @@ -231,14 +231,14 @@ describe('Misc tests', () => { interface Broken { link: string; } - + type WorkingForm = FormType; type BrokenForm = FormType; const fb = new FormBuilder().nonNullable; - - const wf = fb.group({name: fb.control('Name')}); - const bf = fb.group({link: fb.control('Link')}); + + const wf = fb.group({ name: fb.control('Name') }); + const bf = fb.group({ link: fb.control('Link') }); }) it('Undefined value and optional property https://github.com/iamguid/ngx-mf/issues/4', () => { @@ -249,11 +249,11 @@ describe('Misc tests', () => { optionalD?: number | undefined; optionalE?: number | undefined; } - + type OptionalForm = FormType; const fb = new FormBuilder().nonNullable; - + const wf: OptionalForm[T] = fb.group({ // optionalA: fb.control(321), optionalB: fb.control(123), @@ -262,4 +262,67 @@ describe('Misc tests', () => { optionalE: fb.control(432), }); }) + + it('Nested optional properties', () => { + enum ContactType { + Email, + Telephone, + } + + interface IContactModel { + type: ContactType | null; + contact: string | null; + } + + interface IUserModel { + id: number; + firstName: string | null; + lastName: string | null; + nickname: string | null; + birthday?: Date | null; + contacts: IContactModel[]; + } + + + type MainForm = FormType< + Omit, + { contacts: [FormElementGroup] } + >; + type ContactForm = MainForm['contacts']; + + const fb = new FormBuilder(); + + type t = ContactForm[I][T] + + const form: MainForm[T] = fb.group({ + firstName: fb.control(null), + lastName: fb.control(null), + nickname: fb.control(null), + // birthday: fb.control(null), this is now optional <<< + contacts: fb.array([]), + }); + + const value: Omit = { + firstName: 'Vladislav', + lastName: 'Lebedev', + nickname: 'iam.guid', + birthday: new Date('2022-07-15T19:53:07.764Z'), + contacts: [ + { + type: ContactType.Email, + contact: 'iam.guid@gmail.com', + }, + ], + }; + + form.controls.contacts.controls.push( + fb.group({ + type: fb.control(ContactType.Email), + contact: fb.control('test@test.com', Validators.email), + }) + ); + + form.patchValue(value); + + }) })