Reputation: 90188
Update:
At this point, I'm no longer able to repro it on local, after I ran
rm -rf node_mdoules/ && npm i
I'll keep the question, as it might be useful for others experiencing this bug. At the point of this writing, the bug is still reproducible in jsfiddle.
If someone finds a way to repro it reliably, do provide a repo as I know a few passionate coders curious enough to search for its root cause.
Initial question
I have this JavaScript code, which works:
const iconsMap = new Map([
['Roofs', 'roofs'],
['Walls', 'walls'],
['Windows & Doors', 'doors'],
['Heating & Controls', 'heating'],
['Ventilation & Air Tightness', 'ventilation'],
['Renewables', 'renewables'],
['Others', 'others'],
['Default', 'home'],
]);
console.log(
Object.assign({}, ...Array.from(iconsMap).map(([label, fileName]) => ({[label]: fileName})))
);
My first Typescript attempt was very close to original JS:
const iconsMap: Map<string, string> = new Map([
['Roofs', 'roofs'],
['Walls', 'walls'],
['Windows & Doors', 'doors'],
['Heating & Controls', 'heating'],
['Ventilation & Air Tightness', 'ventilation'],
['Renewables', 'renewables'],
['Others', 'others'],
['Default', 'home'],
]);
interface Dictionary<T> {
[key: string]: T;
}
console.log(
Object.assign(
{} as Dictionary<string>,
...Array.from(iconsMap).map(
([label, fileName]) => ({ [label]: fileName })
)
)
);
But it breaks with:
VM325:13 Uncaught SyntaxError: Unexpected token '(' at new Function () at exec (VM319 typescript.js:41)
For some reason, the implied return
of arrow function () => ({})
fails here. I need to do () => { return {}; }
. So this works:
console.log(
Object.assign(
{} as Dictionary<string>,
...Array.from(iconsMap).map(([label, fileName]) => {
return { [label]: fileName };
})
)
);
Could anyone explain why?
Note: I'm not interested in alternative ways to rewrite the above code (it's actually taken out of context to highlight the issue). I already re-rewrote the whole thing, I'm using a .reduce()
and I'm happy enough with it.
For the curious types... cripter, actual implementation:
export const iconRegistry: Dictionary<string> = Array.from(iconsMap)
.reduce((o, [label, fileName]) => ({
...o,
[label]: require(`./assets/icons/measure/${fileName}.svg`)
}), {} as Dictionary<string>);
But I'd like to understand why the implied return
fails above.
Thanks for taking the time.
Upvotes: 2
Views: 178
Reputation:
Your TypeScript code is valid and it's correctly transpiled to JS, at least in TS 3.9.2. It seems to be a jsfiddle bug or a TS bug?. They use TS 1.7.3 in the jsfiddle you linked to, you can verify by executing ts.version
in devtools console.
I added a log breakpoint in the script they use to transpile TS to JS which looks like this:
var transpiled = ts.transpile.apply(ts, [param[0], param[1], "filename", diagnostics]);
new Function(transpiled)();
Logging the transpiled
variable shows that the code was transformed to this:
var iconsMap = new Map([
['Roofs', 'roofs'],
['Walls', 'walls'],
['Windows & Doors', 'doors'],
['Heating & Controls', 'heating'],
['Ventilation & Air Tightness', 'ventilation'],
['Renewables', 'renewables'],
['Others', 'others'],
['Default', 'home'],
]);
console.log(Object.assign({}, ...Array.from(iconsMap).map(function ([label, fileName]) ({ [label]: fileName }))));
Notice that the arrow function was transformed to:
function ([label, fileName]) ({ [label]: fileName })))
Which, of course, is invalid. I'd suggest you to use something like Quokka in vscode or ts-node
if you want some local playground to try out things without having to setup stuff but you can, at least, have control over the TS version you're trying.
Upvotes: 1
Reputation: 276085
The code you have compiles without any errors
For any valid JavaScript Syntax, you will never ever get a SyntaxError if you just copy paste it to a TypeScript file. Because TypeScript is syntactically a strict superset of JavaScript syntax
Upvotes: 3