diff --git a/.gitignore b/.gitignore index e73732d..9e50955 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,5 @@ dist source/*ngfactory.ts source/*ngsummary.json + +*.tgz diff --git a/.npmignore b/.npmignore index fb3fcf4..3c921d6 100644 --- a/.npmignore +++ b/.npmignore @@ -8,3 +8,4 @@ coverage/ .vscode/ docs/ webpack/ +*.tgz diff --git a/package.json b/package.json index 1f1b6a8..78753e6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@angular-redux/form", - "version": "6.5.1", + "version": "6.5.2", "description": "Build Angular 2+ forms with Redux", "dependencies": { "immutable": "^3.8.1" @@ -42,7 +42,7 @@ "reflect-metadata": "^0.1.3", "rimraf": "^2.5.4", "rxjs": "^5.0.1", - "typescript": "^2.1.0", + "typescript": "^2.4.1", "webpack": "^2.1.0-beta.25", "zone.js": "^0.8.4" }, diff --git a/source/compose-reducers.ts b/source/compose-reducers.ts index 3b1c804..726e187 100644 --- a/source/compose-reducers.ts +++ b/source/compose-reducers.ts @@ -1,30 +1,6 @@ import {Reducer, Action} from 'redux'; -import {State} from './state'; - export const composeReducers = - (...reducers: Reducer[]): Reducer => { - // Pull from each reducer its initial state value, from the default - // value of the `state' argument. So we are provided with {initialState}, - // and then with the individual initial states of each reducer. We - // compose all these states together to produce a true 'initial state' - // for our composed reducer. - let state: State = null; - - for (const reducer of reducers) { - const result = reducer.apply(null, [undefined, {type: ''}]); - if (result === undefined) { - continue; - } - - if (state == null) { - state = result; - } - else { - state = State.inspect(state).merge(null, result); - } - } - - return (s: State = state, action: Action) => - reducers.reduce((st, reducer) => reducer(st, action), s); -}; \ No newline at end of file + (...reducers: Reducer[]): Reducer => + (s: State, action: Action) => + reducers.reduce((st, reducer) => reducer(st, action), s); diff --git a/source/connect-array.ts b/source/connect-array.ts index 2605dfe..dd960a5 100644 --- a/source/connect-array.ts +++ b/source/connect-array.ts @@ -43,9 +43,9 @@ import {controlPath, selectValueAccessor} from './shims'; export class ConnectArrayTemplate { constructor( - public $implicit, + public $implicit: any, public index: number, - public item + public item: any ) {} } @@ -85,7 +85,7 @@ export class ConnectArray extends ControlContainer implements OnInit { } @Input() - set connectArrayOf(collection) { + set connectArrayOf(collection: any) { this.key = collection; this.resetState(this.store.getState()); @@ -131,7 +131,7 @@ export class ConnectArray extends ControlContainer implements OnInit { this.formDirective.form.removeControl(this.key); } - private resetState(state) { + private resetState(state: any) { if (this.key == null || this.key.length === 0) { return; // no state to retreive if no key is set } @@ -174,7 +174,7 @@ export class ConnectArray extends ControlContainer implements OnInit { } } - private registerInternals(array) { + private registerInternals(array: any) { array.registerControl = () => {}; array.registerOnChange = () => {}; @@ -188,7 +188,7 @@ export class ConnectArray extends ControlContainer implements OnInit { }); } - private patchDescendantControls(viewRef) { + private patchDescendantControls(viewRef: any) { const groups = Object.keys(viewRef._view) .map(k => viewRef._view[k]) .filter(c => c instanceof NgModelGroup); @@ -205,7 +205,7 @@ export class ConnectArray extends ControlContainer implements OnInit { }); } - private transform(parent: FormGroup | FormArray, reference): AbstractControl { + private transform(parent: FormGroup | FormArray, reference: any): AbstractControl { const emptyControl = () => { const control = new FormControl(null); control.setParent(parent); @@ -227,7 +227,7 @@ export class ConnectArray extends ControlContainer implements OnInit { return emptyControl(); } - const iterate = (iterable): FormArray => { + const iterate = (iterable: any): FormArray => { const array = new FormArray([]); this.registerInternals(array); @@ -246,7 +246,7 @@ export class ConnectArray extends ControlContainer implements OnInit { return array; } - const associate = (value): FormGroup => { + const associate = (value: any): FormGroup => { const group = new FormGroup({}); group.setParent(parent); @@ -280,7 +280,7 @@ export class ConnectArray extends ControlContainer implements OnInit { private simpleAccessor() { return { - writeValue: value => this.control.setValue(value), + writeValue: (value: any) => this.control.setValue(value), registerOnChange() {}, registerOnTouched() {} }; diff --git a/source/connect-base.ts b/source/connect-base.ts index 9f3ff7b..a9f498d 100644 --- a/source/connect-base.ts +++ b/source/connect-base.ts @@ -29,7 +29,7 @@ export class ConnectBase { private formSubscription: Subscription; protected store: FormStore; - protected form; + protected form: any; public get path(): Array { const path = typeof this.connect === 'function' @@ -68,12 +68,14 @@ export class ConnectBase { this.stateSubscription = this.store.subscribe(() => this.resetState()); Promise.resolve().then(() => { - this.formSubscription = (this.form.valueChanges).debounceTime(0).subscribe(values => this.publish(values)); + this.formSubscription = (this.form.valueChanges) + .debounceTime(0) + .subscribe((values: any) => this.publish(values)); }); }); } - private descendants(path: Array, formElement): Array { + private descendants(path: Array, formElement: any): Array { const pairs = new Array(); if (formElement instanceof FormArray) { @@ -122,7 +124,7 @@ export class ConnectBase { }); } - private publish(value) { + private publish(value: any) { this.store.valueChanged(this.path, this.form, value); } diff --git a/source/connect-reactive.ts b/source/connect-reactive.ts index 0f9f867..9d49e50 100644 --- a/source/connect-reactive.ts +++ b/source/connect-reactive.ts @@ -10,7 +10,7 @@ import {ConnectBase} from './connect-base'; // For reactive forms (without implicit NgForm) @Directive({ selector: 'form[connect][formGroup]' }) export class ReactiveConnect extends ConnectBase { - @Input('formGroup') form; + @Input('formGroup') form: any; constructor( protected store: FormStore diff --git a/source/form-reducer.ts b/source/form-reducer.ts index 0eee938..e6f908b 100644 --- a/source/form-reducer.ts +++ b/source/form-reducer.ts @@ -7,7 +7,7 @@ import {FORM_CHANGED} from './form-store'; import {State} from './state'; export const defaultFormReducer = (initialState?: RootState | Iterable.Keyed) => { - const reducer = (state: RootState | Iterable.Keyed = initialState, action: Action & {payload?}) => { + const reducer = (state: RootState | Iterable.Keyed | undefined = initialState, action: Action & {payload?: any}) => { switch (action.type) { case FORM_CHANGED: return State.assign( diff --git a/source/form-store.ts b/source/form-store.ts index c7f751c..43af642 100644 --- a/source/form-store.ts +++ b/source/form-store.ts @@ -8,7 +8,7 @@ import {Action, Unsubscribe} from 'redux'; export interface AbstractStore { /// Dispatch an action - dispatch(action: Action & {payload}): void; + dispatch(action: Action & {payload: any}): void; /// Retrieve the current application state getState(): RootState; @@ -34,7 +34,7 @@ export class FormStore { return this.store.getState(); } - subscribe(fn: (state) => void): Unsubscribe { + subscribe(fn: (state: any) => void): Unsubscribe { return this.store.subscribe(() => fn(this.getState())); } diff --git a/source/shims.ts b/source/shims.ts index 7706206..9fef323 100644 --- a/source/shims.ts +++ b/source/shims.ts @@ -14,12 +14,12 @@ export function controlPath(name: string, parent: ControlContainer): string[] { } export function selectValueAccessor( - dir: NgControl, valueAccessors: ControlValueAccessor[]): ControlValueAccessor { + dir: NgControl, valueAccessors: ControlValueAccessor[]): ControlValueAccessor | null { if (!valueAccessors) return null; - let defaultAccessor: ControlValueAccessor; - let builtinAccessor: ControlValueAccessor; - let customAccessor: ControlValueAccessor; + let defaultAccessor: ControlValueAccessor | null = null; + let builtinAccessor: ControlValueAccessor | null = null; + let customAccessor: ControlValueAccessor | null = null; valueAccessors.forEach((v: ControlValueAccessor) => { if (v.constructor === DefaultValueAccessor) { defaultAccessor = v; diff --git a/source/state.ts b/source/state.ts index 592e11a..671d288 100644 --- a/source/state.ts +++ b/source/state.ts @@ -7,14 +7,14 @@ export interface Operations { clone(): T; /// Clone and merge - merge(key: number | string, value: T); + merge(key: number | string | null, value: T): any; /// Clone the object and update a specific key inside of it - update(key: number | string, value: T); + update(key: number | string | null, value: T): any; } export interface TraverseCallback { - (parent, key: number | string, remainingPath: string[], value?); + (parent: any, key: number | string, remainingPath: string[], value?: any): any; } export abstract class State { @@ -37,7 +37,7 @@ export abstract class State { deepValue = (> deepValue).get(k); } else { - deepValue = deepValue[k]; + deepValue = (deepValue as any)[k]; } if (typeof fn === 'function') { @@ -64,7 +64,7 @@ export abstract class State { return State.traverse(state, path); } - static assign(state: State, path: string[], value?) { + static assign(state: State, path: string[], value?: any) { const operations = State.inspect(state); if (path.length === 0) { @@ -117,7 +117,7 @@ export abstract class State { } static inspect(object: K): Operations { - const metaOperations = (update, merge, clone?) => { + const metaOperations = (update: Function, merge: Function, clone?: Function) => { const operations = { /// Clone the object (shallow) clone: typeof clone === 'function' @@ -130,7 +130,7 @@ export abstract class State { /// Merge existing values with new values merge: (key: string, value: K) => { const cloned = operations.clone(); - return merge(cloned, key, value, v => update(cloned, key, v)); + return merge(cloned, key, value, (v: any) => update(cloned, key, v)); } }; @@ -140,7 +140,7 @@ export abstract class State { if (Iterable.isIterable(object)) { return metaOperations( // Replace - (parent, key: number | string, value: K) => { + (parent: any, key: number | string, value: K) => { if (key != null) { return parent.set(key, value); } @@ -149,7 +149,7 @@ export abstract class State { } }, // Merge - (parent, key: number | string | string[], value: K) => { + (parent: any, key: number | string | string[], value: K) => { if (key) { return parent.mergeDeepIn(Array.isArray(key) ? key : [key], value); } @@ -166,7 +166,7 @@ export abstract class State { else if (Array.isArray(object)) { return metaOperations( // Replace array contents - (parent, key: number, value: K) => { + (parent: any, key: number, value: K) => { if (key != null) { parent[key] = value; } @@ -177,7 +177,7 @@ export abstract class State { }, // Merge - (parent, _, value: K, setter: (v: K) => K) => { + (parent: any, _: any, value: K, setter: (v: K) => K) => { setter(parent.concat(value)); return parent; }, @@ -189,7 +189,7 @@ export abstract class State { else if (object instanceof Map) { return metaOperations( // Update map key - (parent, key: number | string, value: K) => { + (parent: any, key: number | string, value: K) => { if (key != null) { return parent.set(key, value); } @@ -202,7 +202,7 @@ export abstract class State { }, // Merge - (parent: Map, _, value: K) => { + (parent: Map, _: any, value: K) => { const m = new Map( value); m.forEach((value, key) => parent.set(key, value)); return parent; @@ -217,7 +217,7 @@ export abstract class State { else if (object instanceof WeakSet || object instanceof Set) { return metaOperations( // Update element at index in set - (parent, key: number, value: K) => { + (parent: any, key: number, value: K) => { if (key != null) { return parent.set(key, value); } @@ -230,7 +230,7 @@ export abstract class State { }, // Merge - (parent: Set, _, value) => { + (parent: Set, _: any, value: any) => { for (const element of value) { parent.add(element); } @@ -260,15 +260,15 @@ export abstract class State { break; } return metaOperations( - (parent, key, value: K) => { + (parent: any, key: any, value: K) => { if (key != null) { return Object.assign(parent, {[key]: value}); } return Object.assign(parent, value); }, - (parent, _, value: K) => { + (parent: any, _: any, value: K) => { for (const k of Object.keys(value)) { - parent[k] = value[k]; + parent[k] = (value as any)[k]; } return parent; }, @@ -284,7 +284,7 @@ export abstract class State { 'in the mutation path should be an array, an associative container, or a set'); } - static empty(value): boolean { + static empty(value: any): boolean { return value == null || (value.length === 0 || (typeof value.length === 'undefined' && Object.keys(value).length === 0)); diff --git a/tsconfig.json b/tsconfig.json index 75e43dc..a9317fd 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,8 +12,14 @@ "declaration": true, "outDir": "dist", "rootDir": "", + "strict": true, "noUnusedLocals": true, - "noUnusedParameters": true + "noUnusedParameters": true, + "forceConsistentCasingInFileNames": true, + "pretty": true, + + // Work around an issue in Angular itself with TS 2.4.1. + "skipLibCheck": true }, "awesomeTypescriptLoaderOptions": { "emitRequireType": false, diff --git a/yarn.lock b/yarn.lock index 0538c5f..59ad43b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3418,9 +3418,9 @@ type-is@~1.6.14: media-typer "0.3.0" mime-types "~2.1.13" -typescript@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.3.0.tgz#2e63e09284392bc8158a2444c33e2093795c0418" +typescript@latest: + version "2.4.1" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.4.1.tgz#c3ccb16ddaa0b2314de031e7e6fee89e5ba346bc" uglify-js@^2.6, uglify-js@^2.7.5: version "2.7.5"