npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@mjpenza/ngx-strongly-typed-forms

v11.0.3

Published

Strongly typed definitions for Angular's @angular/forms

Downloads

3

Readme

ngx-strongly-typed-forms

How to use?

This is a one off fork of no0x9d/ngx-strongly-typed-forms to add support for Angular 11.

npm install @mjpenza/ngx-strongly-typed-forms

Attention: Since version 7.2 this project does no longer follow semver version numbers. The major and minor version represents the compatible Angular version and patch versions are bugfixes in this library.

Now you can import generic FormControl, FormGroup and FormArray and use them instead of the classes from @angular/forms

import {FormArray, FormControl, FormGroup} from 'ngx-strongly-typed-forms';

If you want to use the FormBuilder you have to provide it from your app module

import { ReactiveFormsModule } from '@angular/forms';
import { NgxStronglyTypedFormsModule } from 'ngx-strongly-typed-forms';

@NgModule({
  imports: [ ReactiveFormsModule, NgxStronglyTypedFormsModule ]
})
export class AppModule {
}

All usages of AbstractControl and its subclasses now supports generic types.

This change is not backwards compatible with Angular's AbstractControl. All occurrence at minimum must be typed with AbstractControl<any>, or at best with an interface which describes all form fields.

How does it work

This project does not modify any angular classes but provides new strongly typed definitions for Angular's own forms. For convenience it re-exports these classes directly from Angular.

Hints

  • When working with FormBuilder and FormGroups always mention the type you want, or else the TypeScript compiler tries to match every property, which does not work with nested FormArrays or FormGroups.
form = fb.group<MyModel>({
  foo: null,
  bar: ["bar", Validators.required],
  baz: fb.array<Baz>([])
})
  • FormArray<T> extends AbstractControl<T[]>. So if you have a FormArray<string> you can assign it to an AbstractControl<string[]>. This is necessary, because for instance FormArray.get returns a single instance of type T but FormArray.value returns T[]. It's also important when working with FormArrays as part of complex FormGroups. The generic type of the FormArray must always be the same as the generic of the Array in the model.

Alternatives

  • Angular's own effort to create typed forms (https://github.com/angular/angular/pull/20040). But it's not yet merged and has - in my opinion - the drawback to fall back to untyped forms too easy. At the current state it also does not support typed FormBuilder.
  • ngx-typed-form provides typed FormBuilder, but does not enforce the structure of any parameters. Because of the chosen implementation FormControl, FormGroup and FormArray are only interfaces and can not be used directly

Something does not work as expected

Beside the known limitations, everything that is possible with the native Angular Forms should be possible too.

If you find something not working as expected then there might be a problem in my type definitions. Please open an issue with an minimal example to reproduce the problem and I will try to fix it asap.

Limitations

  • AbstractControl#value is not correctly typed for TypeScript strict mode. For FormGroup it returns only values of FormControls that are not disabled. So the correct type should be a DeepPartial<T>.

TypeScript 2.8 supports conditional types to build this structure like

type DeepPartial<T> = {
  [P in keyof T]?: T[P] extends Array<infer U>
    ? Array<DeepPartial<U>>
    : T[P] extends ReadonlyArray<infer U>
      ? ReadonlyArray<DeepPartial<U>>
      : DeepPartial<T[P]>
};

When Angular uses TypeScript 2.8 the return value should be changed.

  • The get method on AbstractControl AbstractControl#get(path: string|number []) is impossible to statically type, because every subclass has a different implementation. FormControl always return null, FormGroup only works with string keys and FormArray only with a numerical index. Because I never needed a deeply nested access with both number and string, only string key up to a depth of 5 levels are currently supported. If this is not sufficient for you, please open an issue and explain your situation.
  • Because of it's nature to support only strongly typed forms, forms with dynamically added fields can not be built an a typesafe way. Workaround: Use AbstractControl<any> or an interface with all possible fields set as optional.