Roddy
Roddy

Reputation: 68023

What's the appropriate return type for a Typescript function returning an AsyncFunction?

This code should work OK...

let AsyncFunction = Object.getPrototypeOf(async function(){}).constructor;

export function createJsFunction(event: string, body: string[]): any {
  return new AsyncFunction(body.join("\n") + "\n//# sourceURL=" + event);
}

.. but the "any" return value of createJsFunction offends me. What's the appropriate type to return?

If I'm using the regular Function type, it's obviously just Function... but using AsyncFunction I get Cannot find name 'AsyncFunction'

Upvotes: 0

Views: 187

Answers (1)

Karol Majewski
Karol Majewski

Reputation: 25790

First, we can narrow the type of AsyncFunction a little. The built-in typings say it's any, but we know it's really a FunctionConstructor.

let AsyncFunction: FunctionConstructor = Object.getPrototypeOf(async function () {}).constructor;

Now we can use it just as we would use the standard Function constructor.

const createJsFunction = new AsyncFunction('event', 'body', `
  await body.join('\\n') + '\\n//# sourceURL=' + event
`);

(Note the double backslash inside the template string.)

This works, but the inferred type for createJsFunction is just Function. That's because there is no way for the type system to tell what the result is going to be at compile-time.

If we know what the actual signature will be, we can tell TypeScript about it by using a type assertion (here: as (event: string, body: string[]) => Promise<string>):

const createJsFunction = new AsyncFunction('event', 'body', `
  body.join('\\n') + '\\n//# sourceURL=' + event
`) as (event: string, body: string[]) => Promise<string>;

As you mentioned in your comment, the advantage of using the AsyncFunction constructor is that you can await inside the function you are constructing.

const createJsFunction = new AsyncFunction('event', 'body', `
  await body.join('\\n') + '\\n//# sourceURL=' + event
`) as (event: string, body: string[]) => Promise<void>;

Upvotes: 2

Related Questions