Skip to content

Commit

Permalink
fix: handle 'any' values properly in 'ControlOf' (#60)
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaelss95 committed Nov 22, 2020
1 parent 232fb5e commit 779e083
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
NestedFormControls
} from './mocks.spec';
import { Validators } from '@angular/forms';
import { ControlsOf } from '../types';
import { AbstractControl, ControlsOf } from '../types';

test('control should be constructed with abstract controls', () => {
expectTypeOf(FormGroup).toBeConstructibleWith({ name: new FormControl() });
Expand Down Expand Up @@ -136,7 +136,8 @@ describe('with generic', () => {
a: new FormControl<number>()
})
]),
d: new FormControl<boolean>()
d: new FormControl<boolean>(),
e: new FormControl()
});
expectTypeOf<{
a: FormControl<number>;
Expand All @@ -146,6 +147,7 @@ describe('with generic', () => {
}>;
c: FormArray<FormGroup<{ a: FormControl<number> }>>;
d: FormControl<boolean>;
e: AbstractControl;
}>(a.controls);
});

Expand All @@ -164,7 +166,8 @@ describe('with generic', () => {
c: new FormArray<FormControl<number>>([])
}),
c: new FormControl<{ a: number }[]>(),
d: new FormControl<boolean>()
d: new FormControl<boolean>(),
e: new FormControl()
});
expectTypeOf<{
a: FormControl<number>;
Expand All @@ -174,6 +177,7 @@ describe('with generic', () => {
}>;
c: FormControl<{ a: number }[]>;
d: FormControl<boolean>;
e: AbstractControl;
}>(a.controls);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface NestedForm {
};
c?: { a: number }[];
d?: boolean;
e?: any;
}

export interface NestedFormControls {
Expand Down
13 changes: 7 additions & 6 deletions projects/ngneat/reactive-forms/src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { FormArray } from './formArray';
import { FormControl } from './formControl';
import { FormGroup } from './formGroup';
import { PersistManager } from './persistManager';
import { NestedForm } from './type-tests/mocks.spec';

export type ValidationErrors<T = NgValidationErrors> = T;
export type ValidatorFn<T = any, E = any> = (control: AbstractControl<T>) => ValidationErrors<E> | null;
Expand Down Expand Up @@ -93,9 +92,8 @@ type ExcludeControls<T> = Exclude<T, FormControl | FormGroup | FormArray>;
type AbstractControlOfWithPotentialUnion<T> = [T] extends [AbstractControl]
? T
: [T] extends [Primitive]
? FormControl<T>
: // in case we got no generic in the constructor, resolve the type as Abstract<T>.
T extends unknown
? FormControl<T> // in case we got no generic in the constructor, resolve the type as Abstract<T>.
: T extends unknown
? AbstractControl<ExcludeControls<T>>
: AbstractControl<T>;
export type AbstractControlOf<T> = AbstractControl extends AbstractControlOfWithPotentialUnion<T>
Expand Down Expand Up @@ -133,7 +131,10 @@ export type AbstractControlsOf<T extends Obj> = {
* ])
* });
* */
export type ControlOf<T> = [T] extends [any[]]
type ExtractAny<T> = T extends Extract<T, string & number & boolean & object & null & undefined> ? any : never;
export type ControlOf<T> = [T] extends ExtractAny<T>
? AbstractControl<T>
: [T] extends [any[]]
? FormArray<ControlOf<UnwrapArray<T>>>
: [T] extends [object]
? FormGroup<ControlsOf<T>>
Expand All @@ -142,7 +143,7 @@ export type ControlsOf<T extends Object, TOverrides extends Partial<AbstractCont
[key in keyof T]: unknown extends TOverrides[key] ? ControlOf<T[key]> : TOverrides[key];
};

export type ArrayKeys<T> = { [K in keyof T]: T[K] extends Array<any> ? K : never }[keyof T];
export type ArrayKeys<T> = { [K in keyof T]: T[K] extends any[] ? K : never }[keyof T];
export type ControlFactory<T> = (value: T) => AbstractControl<T>;
export type ControlFactoryMap<T> = {
[K in ArrayKeys<T>]?: ControlFactory<ArrayType<T[K]>>;
Expand Down

0 comments on commit 779e083

Please sign in to comment.