Enforces strictly typed forms in Angular.
Install the library by using npm, pnpm or yarn:
npm install @rytrox/ngx-typed-forms
pnpm install @rytrox/ngx-typed-forms
yarn add @rytrox/ngx-typed-forms
Angular Version | Library Version |
---|---|
^18.2.0 | 1.0.0 - 2.0.1 |
^19.0.0 | ^2.1.1 |
Define your Interface like this:
interface Foo {
id: number;
name: string | null;
date: Date | null
}
Only controls that are declared as optional (by using the ?
operator), are allowed to be registered or removed from the form group.
After you've defined your FormGroup
-interface like above, you can implement a custom FormGroup
like this:
import {FormGroup, FormControl} from "@rytrox/ngx-typed-forms";
export class FooGroup extends FormGroup<Foo> {
public constructor(private input: Foo) {
super({
id: new FormControl({value: input.id, nonNullable: true}),
name: new FormControl(input.name),
date: new FormControl(input.date),
});
}
}
Notice that the name of the form-related classes are the same as angular's native ones.
Over the past years, the famous FormControl
is pretty stuffed with confusing APIs.
Angular 18 introduces the nonNullable
-Flag and deprecated all old constructors as well.
This Library goes a bit further by removing the old constructors and tidy up the new ones
From:
// From:
import {FormControl, Validators} from "@angular/forms";
const form = new FormControl('Hello', [Validators.required], [ /* Async-Validators here */]);
To:
import {FormControl} from "@rytrox/ngx-typed-forms";
import {Validators} from "@angular/forms";
const form = new FormControl('Hello', {validators: [Validators.required()], asyncValidators: [ /* Async-Validators here */ ]});
Angular 18 introduces a Non-Nullable flag inside its options
parameter.
This Library also introduced this feature, but on the state
parameter instead.
From:
import {FormControl} from "@angular/forms";
const form = new FormControl('Hello', {nonNullable: true, validators: [], asyncValidators: []});
To:
import {FormControl} from "@rytrox/ngx-typed-forms";
const form = new FormControl({value: 'Hello', nonNullable: true}, {validators: [], asyncValidators: []});
You are now able to use the internal Angular-Type OptionalKeys<T>
that returns all keys, declared as optional (IDK why they hide this, since that's pretty neat in some cases)
-
While Angular-Forms are more freely, they often have a lack of type safety. We decided to declare every
AbstractControl
without a generic declaration asAbstractControl<unknown>
instead of Angular'sAbstractControl<any>
. -
Angular FormControls should support
undefined
, but changes internally tonull
. Since they don't declare this, I fix that inside the type definition -
Inside Angular, it is allowed to declare a nullable non-nullable FormControl:
import {FormControl} from "@angular/forms"; const form = new FormControl(null, {nonNullable: true}); const value = form.value; // <- This is null...
This happens, because TypeScript constructor declarations are limited. But instead of allowing that, we've decided to set this type to
never
:import {FormControl} from "@rytrox/ngx-typed-forms"; const form = new FormControl({value: null, nonNullable: true}); // Sadly, I can't catch this... const value = form.value; // <- This is never!
-
We introduced in every form a new field called
rawValue
. It returns the raw value of every form. It's just an alternative to thegetRawValue()
method.
Please feel free to contribute to this project
by creating issues or pull requests on our mirror project
Copyright (c) 2024 Team Rytrox
Licensed under the MIT license