@@ -31,6 +31,24 @@ type FilterData = {
3131} ;
3232export type FilterFn = ( p : FilterData ) => Partial < FilterData > ;
3333
34+ type FilterParam < K extends keyof typeof filters > = Parameters <
35+ ( typeof filters ) [ K ]
36+ > [ 0 ] ;
37+
38+ export type FilterInput = {
39+ [ K in keyof typeof filters ] : FilterParam < K > extends undefined
40+ ? // Case 1: Function accepts `undefined` only, return the key as a string literal
41+ K
42+ : undefined extends FilterParam < K >
43+ ? object extends FilterParam < K >
44+ ? // Case 2: Function accepts `object | undefined`, return union of the key or the object
45+ { [ P in K ] : Exclude < FilterParam < K > , undefined > } | K
46+ : // Case 3: Function accepts only `undefined`, return the key as a string literal
47+ K
48+ : // Case 4: Function accepts only an `object`, return object type
49+ { [ P in K ] : FilterParam < K > } ;
50+ } [ keyof typeof filters ] ;
51+
3452const mapNumbers = ( ys : YValue [ ] , fn : ( y : number , i : number ) => number ) =>
3553 ys . map ( ( y , i ) => {
3654 const n = castFloat ( y ) ;
@@ -79,7 +97,7 @@ const filters = {
7997 const mapping = mappingStr . map ( ( str ) => str . split ( "->" ) . map ( parseFloat ) ) ;
8098 const regression = new LinearRegression (
8199 mapping . map ( ( [ x , _y ] ) => x ) ,
82- mapping . map ( ( [ _x , y ] ) => y )
100+ mapping . map ( ( [ _x , y ] ) => y ) ,
83101 ) ;
84102 return {
85103 ys : regression . predict ( ys . map ( castFloat ) ) ,
@@ -150,7 +168,7 @@ const filters = {
150168 unit ?: keyof typeof timeUnits ;
151169 reset_every ?: TimeDurationStr ;
152170 offset ?: TimeDurationStr ;
153- } = "h"
171+ } = "h" ,
154172 ) => {
155173 const param =
156174 typeof unitOrObject == "string" ? { unit : unitOrObject } : unitOrObject ;
@@ -197,7 +215,11 @@ const filters = {
197215 } ;
198216 } ,
199217 sliding_window_moving_average :
200- ( { window_size = 10 , extended = false , centered = true } = { } ) =>
218+ ( {
219+ window_size = 10 ,
220+ extended = false ,
221+ centered = true ,
222+ } : { window_size ?: number ; extended ?: boolean ; centered ?: boolean } = { } ) =>
201223 ( params ) => {
202224 const { xs, ys, ...rest } = force_numeric ( params ) ;
203225 const ys2 : number [ ] = [ ] ;
@@ -227,7 +249,11 @@ const filters = {
227249 return { xs : xs2 , ys : ys2 , ...rest } ;
228250 } ,
229251 median :
230- ( { window_size = 10 , extended = false , centered = true } = { } ) =>
252+ ( {
253+ window_size = 10 ,
254+ extended = false ,
255+ centered = true ,
256+ } : { window_size ?: number ; extended ?: boolean ; centered ?: boolean } = { } ) =>
231257 ( params ) => {
232258 const { xs, ys, ...rest } = force_numeric ( params ) ;
233259 const ys2 : number [ ] = [ ] ;
@@ -257,7 +283,7 @@ const filters = {
257283 return { ys : ys2 , xs : xs2 , ...rest } ;
258284 } ,
259285 exponential_moving_average :
260- ( { alpha = 0.1 } = { } ) =>
286+ ( { alpha = 0.1 } : { alpha ?: number } = { } ) =>
261287 ( params ) => {
262288 const { ys, ...rest } = force_numeric ( params ) ;
263289 let last = ys [ 0 ] ;
@@ -268,37 +294,37 @@ const filters = {
268294 } ,
269295 map_y_numbers : ( fnStr : string ) => {
270296 const fn = myEval (
271- `(i, x, y, state, statistic, xs, ys, states, statistics, meta, vars, hass) => ${ fnStr } `
297+ `(i, x, y, state, statistic, xs, ys, states, statistics, meta, vars, hass) => ${ fnStr } ` ,
272298 ) ;
273299 return ( { xs, ys, states, statistics, meta, vars, hass } ) => ( {
274300 xs,
275301 ys : mapNumbers ( ys , ( _ , i ) =>
276302 // prettier-ignore
277- fn ( i , xs [ i ] , ys [ i ] , states [ i ] , statistics [ i ] , xs , ys , states , statistics , meta , vars , hass )
303+ fn ( i , xs [ i ] , ys [ i ] , states [ i ] , statistics [ i ] , xs , ys , states , statistics , meta , vars , hass ) ,
278304 ) ,
279305 } ) ;
280306 } ,
281307 map_y : ( fnStr : string ) => {
282308 const fn = myEval (
283- `(i, x, y, state, statistic, xs, ys, states, statistics, meta, vars, hass) => ${ fnStr } `
309+ `(i, x, y, state, statistic, xs, ys, states, statistics, meta, vars, hass) => ${ fnStr } ` ,
284310 ) ;
285311 return ( { xs, ys, states, statistics, meta, vars, hass } ) => ( {
286312 xs,
287313 ys : ys . map ( ( _ , i ) =>
288314 // prettier-ignore
289- fn ( i , xs [ i ] , ys [ i ] , states [ i ] , statistics [ i ] , xs , ys , states , statistics , meta , vars , hass )
315+ fn ( i , xs [ i ] , ys [ i ] , states [ i ] , statistics [ i ] , xs , ys , states , statistics , meta , vars , hass ) ,
290316 ) ,
291317 } ) ;
292318 } ,
293319 map_x : ( fnStr : string ) => {
294320 const fn = myEval (
295- `(i, x, y, state, statistic, xs, ys, states, statistics, meta, vars, hass) => ${ fnStr } `
321+ `(i, x, y, state, statistic, xs, ys, states, statistics, meta, vars, hass) => ${ fnStr } ` ,
296322 ) ;
297323 return ( { xs, ys, states, statistics, meta, vars, hass } ) => ( {
298324 ys,
299325 xs : xs . map ( ( _ , i ) =>
300326 // prettier-ignore
301- fn ( i , xs [ i ] , ys [ i ] , states [ i ] , statistics [ i ] , xs , ys , states , statistics , meta , vars , hass )
327+ fn ( i , xs [ i ] , ys [ i ] , states [ i ] , statistics [ i ] , xs , ys , states , statistics , meta , vars , hass ) ,
302328 ) ,
303329 } ) ;
304330 } ,
@@ -357,31 +383,31 @@ const filters = {
357383 throw new Error (
358384 `Trendline '${ p . type } ' doesn't exist. Did you mean <b>${ propose (
359385 p . type ,
360- Object . keys ( trendlineTypes )
361- ) } <b>?\nOthers: ${ Object . keys ( trendlineTypes ) } `
386+ Object . keys ( trendlineTypes ) ,
387+ ) } <b>?\nOthers: ${ Object . keys ( trendlineTypes ) } `,
362388 ) ;
363389 }
364390 const regression : BaseRegression = new RegressionClass (
365391 xs_numbers ,
366392 ys ,
367- p . degree
393+ p . degree ,
368394 ) ;
369395 let extras : string [ ] = [ ] ;
370396 if ( p . show_r2 )
371397 extras . push (
372- `r²=${ maxDecimals ( regression . score ( xs_numbers , ys ) . r2 , 2 ) } `
398+ `r²=${ maxDecimals ( regression . score ( xs_numbers , ys ) . r2 , 2 ) } ` ,
373399 ) ;
374400
375401 if ( forecast > 0 ) {
376402 const N = Math . round (
377403 ( xs_numbers . length /
378404 ( xs_numbers [ xs_numbers . length - 1 ] - xs_numbers [ 0 ] ) ) *
379- forecast
405+ forecast ,
380406 ) ;
381407 xs_numbers . push (
382408 ...Array . from ( { length : N } ) . map (
383- ( _ , i ) => t1 - t0 + ( forecast / N ) * i
384- )
409+ ( _ , i ) => t1 - t0 + ( forecast / N ) * i ,
410+ ) ,
385411 ) ;
386412 }
387413 const ys_out = regression . predict ( xs_numbers ) ;
@@ -405,12 +431,12 @@ const filters = {
405431 */
406432 filter : ( fnStr : string ) => {
407433 const fn = myEval (
408- `(i, x, y, state, statistic, xs, ys, states, statistics, meta, vars, hass) => ${ fnStr } `
434+ `(i, x, y, state, statistic, xs, ys, states, statistics, meta, vars, hass) => ${ fnStr } ` ,
409435 ) ;
410436 return ( { xs, ys, states, statistics, meta, vars, hass } ) => {
411437 const mask = ys . map ( ( _ , i ) =>
412438 // prettier-ignore
413- fn ( i , xs [ i ] , ys [ i ] , states [ i ] , statistics [ i ] , xs , ys , states , statistics , meta , vars , hass )
439+ fn ( i , xs [ i ] , ys [ i ] , states [ i ] , statistics [ i ] , xs , ys , states , statistics , meta , vars , hass ) ,
414440 ) ;
415441 return {
416442 ys : ys . filter ( ( _ , i ) => mask [ i ] ) ,
@@ -425,7 +451,7 @@ export default filters;
425451function checkTimeUnits ( unit : string ) {
426452 if ( ! timeUnits [ unit ] ) {
427453 throw new Error (
428- `Unit '${ unit } ' is not valid, use ${ Object . keys ( timeUnits ) } `
454+ `Unit '${ unit } ' is not valid, use ${ Object . keys ( timeUnits ) } ` ,
429455 ) ;
430456 }
431457}
0 commit comments