From 7fe92ed685e941f3bb4611ede89cd2ad63fecca5 Mon Sep 17 00:00:00 2001 From: James Daniels Date: Tue, 17 Dec 2019 09:05:36 -0800 Subject: [PATCH] More strict types --- src/remote-config/remote-config.ts | 48 +++++++++++++++++++----------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/src/remote-config/remote-config.ts b/src/remote-config/remote-config.ts index 6433b1961..9ac678a85 100644 --- a/src/remote-config/remote-config.ts +++ b/src/remote-config/remote-config.ts @@ -1,5 +1,5 @@ import { Injectable, Inject, Optional, NgZone, InjectionToken, PLATFORM_ID } from '@angular/core'; -import { Observable, concat, of, pipe, OperatorFunction } from 'rxjs'; +import { Observable, concat, of, pipe, OperatorFunction, MonoTypeOperatorFunction } from 'rxjs'; import { map, switchMap, tap, shareReplay, distinctUntilChanged, filter, groupBy, mergeMap, scan, withLatestFrom, startWith, debounceTime } from 'rxjs/operators'; import { FirebaseAppConfig, FirebaseOptions, ɵlazySDKProxy, FIREBASE_OPTIONS, FIREBASE_APP_NAME } from '@angular/fire'; import { remoteConfig } from 'firebase/app'; @@ -65,9 +65,9 @@ export class AngularFireRemoteConfig { readonly changes: Observable; readonly parameters: Observable; - readonly numbers: Observable<{[key:string]: number}> & {[key:string]: Observable}; - readonly booleans: Observable<{[key:string]: boolean}> & {[key:string]: Observable}; - readonly strings: Observable<{[key:string]: string}> & {[key:string]: Observable}; + readonly numbers: Observable<{[key:string]: number|undefined}> & {[key:string]: Observable}; + readonly booleans: Observable<{[key:string]: boolean|undefined}> & {[key:string]: Observable}; + readonly strings: Observable<{[key:string]: string|undefined}> & {[key:string]: Observable}; constructor( @Inject(FIREBASE_OPTIONS) options:FirebaseOptions, @@ -154,7 +154,7 @@ const scanToParametersArray = (remoteConfig: Observable (source: Observable) => new Observable(observer => { +export const budget = (interval: number): MonoTypeOperatorFunction => (source: Observable) => new Observable(observer => { let timedOut = false; // TODO use scheduler task rather than settimeout const timeout = setTimeout(() => { @@ -177,30 +177,44 @@ const typedMethod = (it:any) => { } }; -export function scanToObject(): OperatorFunction; -export function scanToObject(as: 'numbers'): OperatorFunction; -export function scanToObject(as: 'booleans'): OperatorFunction; -export function scanToObject(as: 'strings'): OperatorFunction; +export function scanToObject(): OperatorFunction; +export function scanToObject(to: 'numbers'): OperatorFunction; +export function scanToObject(to: 'booleans'): OperatorFunction; +export function scanToObject(to: 'strings'): OperatorFunction; export function scanToObject(template: T): OperatorFunction; -export function scanToObject(as: 'numbers'|'booleans'|'strings'|ConfigTemplate = 'strings') { +export function scanToObject(to: 'numbers'|'booleans'|'strings'|T = 'strings') { return pipe( // TODO cleanup - scan((c, p: Parameter) => ({...c, [p.key]: typeof as === 'object' ? p[typedMethod(as[p.key])]() : p[AS_TO_FN[as]]()}), typeof as === 'object' ? as : {} as {[key:string]: number|boolean|string}), + scan( + (c, p: Parameter) => ({...c, [p.key]: typeof to === 'object' ? + p[typedMethod(to[p.key])]() : + p[AS_TO_FN[to]]() }), + typeof to === 'object' ? + to as T & {[key:string]: string|undefined}: + {} as {[key:string]: number|boolean|string} + ), debounceTime(1), budget(10), distinctUntilChanged((a,b) => JSON.stringify(a) === JSON.stringify(b)) ); }; -export function mapToObject(): OperatorFunction; -export function mapToObject(as: 'numbers'): OperatorFunction; -export function mapToObject(as: 'booleans'): OperatorFunction; -export function mapToObject(as: 'strings'): OperatorFunction; +export function mapToObject(): OperatorFunction; +export function mapToObject(to: 'numbers'): OperatorFunction; +export function mapToObject(to: 'booleans'): OperatorFunction; +export function mapToObject(to: 'strings'): OperatorFunction; export function mapToObject(template: T): OperatorFunction; -export function mapToObject(as: 'numbers'|'booleans'|'strings'|ConfigTemplate = 'strings') { +export function mapToObject(to: 'numbers'|'booleans'|'strings'|T = 'strings') { return pipe( // TODO this is getting a little long, cleanup - map((params: Parameter[]) => params.reduce((c, p) => ({...c, [p.key]: typeof as === 'object' ? p[typedMethod(as[p.key])]() : p[AS_TO_FN[as]]()}), typeof as === 'object' ? as : {} as {[key:string]: number|boolean|string})), + map((params: Parameter[]) => params.reduce( + (c, p) => ({...c, [p.key]: typeof to === 'object' ? + p[typedMethod(to[p.key])]() : + p[AS_TO_FN[to]]() }), + typeof to === 'object' ? + to as T & {[key:string]: string|undefined} : + {} as {[key:string]: number|boolean|string} + )), distinctUntilChanged((a,b) => JSON.stringify(a) === JSON.stringify(b)) ); };