@@ -29,6 +29,12 @@ const debounceFrequentCall = 1000 * 60 * 5;
2929// For calls that are less likely to happen during a session (go-to-def, workspace symbols).
3030const debounceRareCall = 1000 * 60 ;
3131
32+ type Awaited < T > = T extends PromiseLike < infer U > ? U : T ;
33+ type MiddleWareMethods = {
34+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
35+ [ P in keyof Middleware ] -?: NonNullable < Middleware [ P ] > extends ( ...args : any ) => any ? Middleware [ P ] : never ;
36+ } ;
37+
3238/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
3339/* eslint-disable prefer-rest-params */
3440/* eslint-disable consistent-return */
@@ -159,7 +165,10 @@ export class LanguageClientMiddlewareBase implements Middleware {
159165 debounceFrequentCall ,
160166 'provideCompletionItem' ,
161167 arguments ,
162- ( result ) => {
168+ ( _ , result ) => {
169+ if ( ! result ) {
170+ return { resultLength : 0 } ;
171+ }
163172 const resultLength = Array . isArray ( result ) ? result . length : result . items . length ;
164173 return { resultLength } ;
165174 } ,
@@ -441,17 +450,16 @@ export class LanguageClientMiddlewareBase implements Middleware {
441450 return args [ args . length - 1 ] ( ...args ) ;
442451 }
443452
444- private callNextAndSendTelemetry (
453+ private callNextAndSendTelemetry < T extends keyof MiddleWareMethods > (
445454 lspMethod : string ,
446455 debounceMilliseconds : number ,
447- funcName : keyof Middleware ,
456+ funcName : T ,
448457 args : IArguments ,
449- lazyMeasures ?: ( this_ : any , result : any ) => Record < string , number > ,
450- ) {
458+ lazyMeasures ?: ( this_ : any , result : Awaited < ReturnType < MiddleWareMethods [ T ] > > ) => Record < string , number > ,
459+ ) : ReturnType < MiddleWareMethods [ T ] > {
451460 const now = Date . now ( ) ;
452461 const stopWatch = new StopWatch ( ) ;
453462 let calledNext = false ;
454-
455463 // Change the 'last' argument (which is our next) in order to track if
456464 // telemetry should be sent or not.
457465 const changedArgs = [ ...args ] ;
@@ -473,7 +481,7 @@ export class LanguageClientMiddlewareBase implements Middleware {
473481 }
474482 const lastCapture = this . lastCaptured . get ( lspMethod ) ;
475483
476- const sendTelemetry = ( result : any ) => {
484+ const sendTelemetry = ( result : Awaited < ReturnType < MiddleWareMethods [ T ] > > ) => {
477485 // Skip doing anything if not allowed
478486 // We should have:
479487 // - called the next function in the middleware (this means a request was actually sent)
@@ -511,12 +519,12 @@ export class LanguageClientMiddlewareBase implements Middleware {
511519 } ;
512520
513521 // Try to call the 'next' function in the middleware chain
514- const result = this . callNext ( funcName , changedArgs as any ) ;
522+ const result : ReturnType < MiddleWareMethods [ T ] > = this . callNext ( funcName , changedArgs as any ) ;
515523
516524 // Then wait for the result before sending telemetry
517- if ( isThenable < any > ( result ) ) {
525+ if ( isThenable ( result ) ) {
518526 return result . then ( sendTelemetry ) ;
519527 }
520- return sendTelemetry ( result ) ;
528+ return sendTelemetry ( result as any ) as ReturnType < MiddleWareMethods [ T ] > ;
521529 }
522530}
0 commit comments