@@ -9,9 +9,11 @@ import { BaseQuery } from '../adapter';
99
1010import type { ErrorReporter } from './ErrorReporter' ;
1111
12+ export type ToString = { toString ( ) : string } ;
13+
1214interface CubeDefinition {
1315 name : string ;
14- extends ?: string ;
16+ extends ?: ( ... args : Array < unknown > ) => { __cubeName : string } ;
1517 measures ?: Record < string , any > ;
1618 dimensions ?: Record < string , any > ;
1719 segments ?: Record < string , any > ;
@@ -292,7 +294,8 @@ export class CubeSymbols {
292294 // If the hierarchy is included all members from it should be included as well
293295 // Extend `includes` with members from hierarchies that should be auto-included
294296 const cubes = type === 'dimensions' ? cube . cubes . map ( ( it ) => {
295- const fullPath = this . evaluateReferences ( null , it . joinPath , { collectJoinHints : true } ) ;
297+ // TODO recheck `it.joinPath` typing
298+ const fullPath = this . evaluateReferences ( null , it . joinPath as ( ) => ToString , { collectJoinHints : true } ) ;
296299 const split = fullPath . split ( '.' ) ;
297300 const cubeRef = split [ split . length - 1 ] ;
298301
@@ -332,7 +335,8 @@ export class CubeSymbols {
332335 const hierarchy = this . getResolvedMember ( type , cubeName , hierarchyName ) ;
333336
334337 if ( hierarchy ) {
335- const levels = this . evaluateReferences ( cubeName , this . getResolvedMember ( 'hierarchies' , cubeName , hierarchyName ) . levels , { originalSorting : true } ) ;
338+ // TODO recheck `this.getResolvedMember(...).levels` typing
339+ const levels = this . evaluateReferences ( cubeName , this . getResolvedMember ( 'hierarchies' , cubeName , hierarchyName ) . levels as ( ) => Array < ToString > , { originalSorting : true } ) ;
336340
337341 levels . forEach ( ( level ) => autoIncludeMembers . add ( level ) ) ;
338342 }
@@ -370,7 +374,8 @@ export class CubeSymbols {
370374
371375 protected membersFromCubes ( parentCube : CubeDefinition , cubes : any [ ] , type : string , errorReporter : ErrorReporter , splitViews : SplitViews , memberSets : any ) {
372376 return R . unnest ( cubes . map ( cubeInclude => {
373- const fullPath = this . evaluateReferences ( null , cubeInclude . joinPath , { collectJoinHints : true } ) ;
377+ // TODO recheck `cubeInclude.joinPath` typing
378+ const fullPath = this . evaluateReferences ( null , cubeInclude . joinPath as ( ) => ToString , { collectJoinHints : true } ) ;
374379 const split = fullPath . split ( '.' ) ;
375380 const cubeReference = split [ split . length - 1 ] ;
376381 const cubeName = cubeInclude . alias || cubeReference ;
@@ -453,7 +458,7 @@ export class CubeSymbols {
453458 return includes . filter ( include => ! excludesMap . has ( include . member ) ) ;
454459 }
455460
456- protected membersFromIncludeExclude ( referencesFn : any , cubeName : string , type : string ) {
461+ protected membersFromIncludeExclude ( referencesFn : ( ... args : Array < unknown > ) => Array < ToString > , cubeName : string , type : string ) {
457462 const references = this . evaluateReferences ( cubeName , referencesFn ) ;
458463 return R . unnest ( references . map ( ( ref : string ) => {
459464 const path = ref . split ( '.' ) ;
@@ -550,7 +555,12 @@ export class CubeSymbols {
550555 return res ;
551556 }
552557
553- protected evaluateReferences ( cube , referencesFn , options : any = { } ) {
558+ protected evaluateReferences < T extends ToString | Array < ToString > > (
559+ cube : string | null ,
560+ referencesFn : ( ...args : Array < unknown > ) => T ,
561+ options : { collectJoinHints ?: boolean , originalSorting ?: boolean } = { }
562+ ) :
563+ T extends Array < ToString > ? Array < string > : T extends ToString ? string : string | Array < string > {
554564 const cubeEvaluator = this ;
555565
556566 const fullPath = ( joinHints , path ) => {
@@ -561,7 +571,7 @@ export class CubeSymbols {
561571 }
562572 } ;
563573
564- const arrayOrSingle = cubeEvaluator . resolveSymbolsCall ( referencesFn , ( name ) => {
574+ const arrayOrSingle : T = cubeEvaluator . resolveSymbolsCall ( referencesFn , ( name ) => {
565575 const referencedCube = cubeEvaluator . symbols [ name ] && name || cube ;
566576 const resolvedSymbol =
567577 cubeEvaluator . resolveSymbol (
@@ -582,25 +592,35 @@ export class CubeSymbols {
582592 collectJoinHints : options . collectJoinHints ,
583593 } ) ;
584594 if ( ! Array . isArray ( arrayOrSingle ) ) {
585- return arrayOrSingle . toString ( ) ;
595+ // arrayOrSingle is of type `T`, and we just checked that it is not an array
596+ // Which means it `T` be an object with `toString`, and result must be `string`
597+ // For any branch of return type that can can contain just an object it's OK to return string
598+ return arrayOrSingle . toString ( ) as any ;
586599 }
587600
588- const references = arrayOrSingle . map ( p => p . toString ( ) ) ;
589- return options . originalSorting ? references : R . sortBy ( R . identity , references ) ;
601+ const references : Array < string > = arrayOrSingle . map ( p => p . toString ( ) ) ;
602+ // arrayOrSingle is of type `T`, and we just checked that it is an array
603+ // Which means that both `T` and result must be arrays
604+ // For any branch of return type that can contain array it's OK to return array
605+ return options . originalSorting ? references : R . sortBy ( R . identity , references ) as any ;
590606 }
591607
592608 public pathFromArray ( array ) {
593609 return array . join ( '.' ) ;
594610 }
595611
596- protected resolveSymbolsCall ( func , nameResolver , context ?: any ) {
612+ protected resolveSymbolsCall < T > (
613+ func : ( ...args : Array < unknown > ) => T | DynamicReference < T > ,
614+ nameResolver : ( id : string ) => unknown ,
615+ context ?: unknown ,
616+ ) : T {
597617 const oldContext = this . resolveSymbolsCallContext ;
598618 this . resolveSymbolsCallContext = context ;
599619 try {
600620 // eslint-disable-next-line prefer-spread
601- let res = func . apply ( null , this . funcArguments ( func ) . map ( ( id ) => nameResolver ( id . trim ( ) ) ) ) ;
621+ const res = func . apply ( null , this . funcArguments ( func ) . map ( ( id ) => nameResolver ( id . trim ( ) ) ) ) ;
602622 if ( res instanceof DynamicReference ) {
603- res = res . fn . apply ( null , res . memberNames . map ( ( id ) => nameResolver ( id . trim ( ) ) ) ) ;
623+ return res . fn . apply ( null , res . memberNames . map ( ( id ) => nameResolver ( id . trim ( ) ) ) ) ;
604624 }
605625 return res ;
606626 } finally {
0 commit comments