UNPKG

ngx-forms-typed

Version:

Angular Forms Typed provides types and helper functions fully compatible with original Angular forms

129 lines (128 loc) 6.99 kB
import { AbstractControl, AbstractControlOptions, AsyncValidatorFn, UntypedFormArray, UntypedFormControl, UntypedFormGroup, ValidatorFn } from '@angular/forms'; import { Observable } from 'rxjs'; /** * Type encapsulating the Angular Form options: * `emitEvent` - do we emit event; * `onlySelf` - do we bubble up to parent * `emitModelToViewChange` - When true or not supplied (the default), each change triggers an onChange event to update the view. * `emitViewToModelChange` - When true or not supplied (the default), each change triggers an ngModelChange event to update the model. */ export interface FormEventOptions { emitEvent?: boolean; onlySelf?: boolean; emitModelToViewChange?: boolean; emitViewToModelChange?: boolean; } /** * A type wrapper around the reset value. It could be partial of the type of the form. Or even describe which form fields are to be disabled */ export type ResetValue<K> = Partial<{ [key in keyof K]: K[key] | { value: K[key]; disabled: boolean; }; }>; /** * Typed form control is an `AbstractControl` with strong typed properties and methods. Can be created using `typedFormControl` function * * @example * const c = typedFormControl<string>(): TypedFormControl<string>; * c.valueChanges // Observable<string> * c.patchValue('s') // expects string * c.patchValue(1) // COMPILE TIME! type error! */ export interface TypedFormControl<K> extends UntypedFormControl, AbstractControl { valueChanges: Observable<K>; statusChanges: Observable<'VALID' | 'INVALID' | 'PENDING' | 'DISABLED'>; patchValue: (v: Partial<K>, options?: FormEventOptions) => void; setValue: (v: K, options?: FormEventOptions) => void; value: K; reset: (value?: ResetValue<K>, opts?: FormEventOptions) => void; } /** * A helper function to create a `TypedFormControl`. It only calls the constructor of FormControl, but **strongly types** the result. * @param v the value to initialize our `TypedFormControl` with - same as in `new FormControl(v, validators, asyncValidators)` * @param validators validators - same as in new `FormControl(v, validators, asyncValidators)` * @param asyncValidators async validators - same as in `new FormControl(v, validators, asyncValidators)` * * @example * const c = typedFormControl<string>(): TypedFormControl<string>; * c.valueChanges // Observable<string> * c.patchValue('s') // expects string * c.patchValue(1) // COMPILE TIME! type error! */ export declare function typedFormControl<T>(v?: T | { value: T; disabled: boolean; }, validatorsOrOptions?: ValidatorFn | ValidatorFn[] | AbstractControlOptions, asyncValidators?: AsyncValidatorFn | AsyncValidatorFn[]): TypedFormControl<T>; /** * Typed form control is an `FormArray` with strong typed properties and methods. Can be created using `typedFormArray` function * * @example * const c = typedFormArray<string>([typedFormControl('of type string')]): TypedFormArray<string[], string>; * c.valueChanges // Observable<string[]> * c.patchValue(['s']) // expects string[] * c.patchValue(1) // COMPILE TIME! type error! */ export interface TypedFormArray<K extends Array<T> = any[], T = any> extends UntypedFormArray { valueChanges: Observable<K>; statusChanges: Observable<'VALID' | 'INVALID' | 'PENDING' | 'DISABLED'>; patchValue: (v: K, options?: FormEventOptions) => void; setValue: (v: K, options?: FormEventOptions) => void; controls: Array<TypedFormControl<T>>; push: (control: TypedFormControl<T>) => void; insert: (index: number, control: TypedFormControl<T>) => void; at: (index: number) => TypedFormControl<T>; setControl: (index: number, control: TypedFormControl<T>) => void; value: K; } /** * A helper function to create a `TypedFormArray`. It only calls the constructor of FormArray, but **strongly types** the result. * @param v the value to initialize our `TypedFormArray` with - same as in `new TypedFormArray(v, validators, asyncValidators)` * @param validators validators - same as in new `TypedFormArray(v, validators, asyncValidators)` * @param asyncValidators async validators - same as in `new TypedFormArray(v, validators, asyncValidators)` * * @example * const c = typedFormArray<string>([typedFormControl('of type string')]): TypedFormArray<string[], string>; * c.valueChanges // Observable<string[]> * c.patchValue(['s']) // expects string[] * c.patchValue(1) // COMPILE TIME! type error! */ export declare function typedFormArray<T = any, K extends Array<T> = T[]>(controls: Array<TypedFormControl<T>>, validatorOrOptions?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null, asyncValidators?: AsyncValidatorFn | AsyncValidatorFn[] | null): TypedFormArray<K, T>; export type Controls<K> = TypedControlsIn<K> | { [k in keyof K]: K[k] extends Array<infer T> ? TypedFormControl<K[k]> | TypedFormGroup<K[k]> | TypedFormArray<K[k], T> : TypedFormControl<K[k]> | TypedFormGroup<K[k]>; }; type NonGroup = string | number | boolean | Function | null | undefined | never; /** * This is a strongly typed thin wrapper type around `FormGroup`. * Can be created using the `typedFormGroup` function */ export type TypedFormGroup<K, C extends Controls<K> = TypedControlsIn<K>> = K extends NonGroup ? never : UntypedFormGroup & TypedFormControl<K> & { controls: K extends NonGroup ? never : C; valueChanges: Observable<K>; statusChanges: Observable<'VALID' | 'INVALID' | 'PENDING' | 'DISABLED'>; patchValue: (v: Partial<K>, options?: FormEventOptions) => void; setValue: (v: K, options?: FormEventOptions) => void; value: K; setControl: <T extends keyof C>(name: T extends string ? T : never, control: C[T]) => void; reset: (value?: ResetValue<K>, options?: FormEventOptions) => void; getRawValue: () => K; }; export declare function typedFormGroup<K, C extends Controls<K> = TypedControlsIn<K>, Key extends keyof K = keyof K>(controls: K extends NonGroup ? never : C, validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null): TypedFormGroup<K, C> & { keys: Record<Key, string>; }; /** * Helper type for specifying what control we expect for each property from the model. */ export type TypedControlsIn<K, groups extends keyof K = never, arrays extends keyof K = never> = { [key in keyof K]-?: key extends groups ? TypedFormGroup<K[key]> : key extends arrays ? K[key] extends Array<infer T> ? TypedFormArray<T[], T> : never : TypedFormControl<K[key]>; }; /** * Shorthand for a model with `TypedFormControl`s and `TypedFormArray`s only (i.e. no `TypedFormGroup`s in) */ export type TypedArraysIn<K, arrays extends keyof K> = TypedControlsIn<K, never, arrays>; /** * Shorthand for a model with `TypedFormControl`s and `TypedFormGroup`s only (i.e. no `TypedFormArray`s in) */ export type TypedGroupsIn<K, groups extends keyof K> = TypedControlsIn<K, groups, never>; export {};