Explosion Pills
Explosion Pills

Reputation: 191729

Specify return type based on return type of generic function

I'm working on adding types for a third party library; specifically blessed.

The Program class has a function that takes a callback and runs return callback: https://github.com/chjj/blessed/blob/master/lib/program.js#L2866

A stripped-down version of this:

Program.prototype.saveReportedCursor = function (callback) {
  if (!callback) return;
  return callback();
}

This means that the callback is optional, but if it's called the class function will return whatever is returned by callback. This is probably nothing at all and should be nothing at all, but I'm just wondering how I can specify this as a type:

// program.d.ts
export class Program {
  saveReportedCursor(callback: Function): <return value of Function>;
}

I've tried using saveReportedCursor<T>(callback: <T>() => T?): T;. This does work, but it's inaccurate since the callback can take arguments and also you would have to set the generic type on saveReportedCursor rather than TypeScript using the return value of the callback when it's defined.

Is there any way for a class function to use the return type of a function argument as its return type when it's not known ahead of time?

Upvotes: 0

Views: 277

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249476

You are close the callback itself does not have to be generic, only the function:

export class Program {
    // public signatures
    saveReportedCursor(): void
    saveReportedCursor<T>(callback?: () => T): T
    // implementation signature
    saveReportedCursor<T>(callback?: () => T): T {
        return callback();
    }
}

let x = new Program().saveReportedCursor(() => 10); // x is number
new Program().saveReportedCursor(); // Return type is void if no callback is spcified

Upvotes: 2

Related Questions