TypeScript Arrow Function To String Changes Syntax

Viewed 250

JavaScript has no problem, it sees an anonymous arrow function and it's .toString() method returns exactly that.

// This returns as expected
// ie `() => ""`
const t = [() => ""];
console.log(t[0].toString());

This example uses Babel, but the same happens in TypeScript. TypeScript sees an anonymous arrow function and tries to create an anonymous function statement which is invalid if trying to run eval on it.

// This returns an incomplete function string
const t = [() => ""]
console.log(t[0].toString());

Running eval(t[0].toString()) will return error:

SyntaxError: Function statements require a function name

Is there a way to preserve the correct syntax when using Babel/TypeScript? Is there some other better way of acheiving this?

1 Answers

The resulting string is:

function () { return ""; }

This cannot be parsed properly because, as the error you read says:

Function statements require a function name

function () { return ""; }

Without a name, it can only exist in an expression context. This works when Babel is not used because standalone arrow function expressions are syntactically permitted, but standalone nameless function expressions are not.

One way would be to assign the function to a variable when evaling:

var t = [function() { return "abc"; }]
var result = eval(`var fn = ${t[0].toString()}; fn();`);
console.log('result:', result);

(But you should also consider if eval is really necessary - in many cases, its use indicates an inelegant X solution to an XY problem - consider if there's any way you can refactor your script to avoid the eval. Occasionally, eval is necessary, but often it's not.)

Related