Reputation: 68023
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
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