【问题标题】:Why implied `return` of arrow function doesn't work in this case (TS)?为什么在这种情况下(TS),箭头函数的隐含“返回”不起作用?
【发布时间】:2020-08-18 01:04:05
【问题描述】:

更新:

此时,在我运行后,我无法再在本地复制它

rm -rf node_mdoules/ && npm i

我会保留这个问题,因为它可能对遇到此错误的其他人有用。在撰写本文时,该错误仍然可以在 jsfiddle 中重现。

如果有人找到了可靠地复制它的方法,请提供一个 repo,因为我知道一些充满热情的编码人员好奇地寻找其根本原因。


初始问题

我有这个 JavaScript 代码,它可以工作:

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})))
);

我的第一次 Typescript 尝试非常接近原始 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 })
    )
  )
);

但它打破了:

VM325:13 Uncaught SyntaxError: Unexpected token '(' 在新函数 () 在 exec (VM319 typescript.js:41)

由于某种原因,箭头函数() =&gt; ({}) 的隐含return 在此处失败。我需要做() =&gt; { return {}; }。所以这行得通:

console.log(
  Object.assign(
    {} as Dictionary<string>,
    ...Array.from(iconsMap).map(([label, fileName]) => {
      return { [label]: fileName };
    })
  )
);

谁能解释一下原因?

注意:我对重写上述代码的替代方法不感兴趣(实际上是断章取义以突出问题)。我已经重写了整个内容,我正在使用.reduce(),我对此感到非常满意。
对于好奇的类型... cript,实际实现:

export const iconRegistry: Dictionary<string> = Array.from(iconsMap)
  .reduce((o, [label, fileName]) => ({
    ...o,
    [label]: require(`./assets/icons/measure/${fileName}.svg`)
  }), {} as Dictionary<string>);

但我想了解为什么上面隐含的 return 会失败。

感谢您抽出宝贵时间。

【问题讨论】:

  • typescript.js(大概是它的编译结果?)包含什么?
  • 看起来像这样:console.log(Object.assign({}, ...Array.from(iconsMap).map(function ([label, fileName]) ({ [label]: fileName }))));。这是a fiddle
  • (另外,你使用的是哪个版本的Node,你确定TypeScript编译步骤成功了吗?TypeScript成功编译成语法无效的JavaScript会很奇怪。)
  • 您能否确保您使用的是最新版本的 TypeScript 编译器,并升级到受支持的 Node (14) 版本?
  • 我发现 TypeScript JSFiddle 使用的版本是:1.7.3,相当过时(仍然不是我期望的稳定版本的那种错误,但是……)。您是在调用 tsc(就像您尝试过 tsc --version 一样)进行编译,还是通过其他工具进行编译?

标签: javascript typescript arrow-functions


【解决方案1】:

你的代码编译without any errors

更多

对于任何有效的 JavaScript 语法,如果您只是将其复制粘贴到 TypeScript 文件中,您将永远不会收到 SyntaxError。因为TypeScript is syntactically a strict superset of JavaScript syntax

【讨论】:

  • 这就是我的想法,这就是为什么我看到它失败时如此惊讶的原因。但是,这并不能回答我的问题。它在链接的小提琴中失败了吗?如果是这样,你能解释一下原因吗?
  • @tao 我最初的解释是,您可能使用的是旧版本的 TypeScript,它不支持 ECMAScript 2017+ 语言功能。您需要从命令行运行 tsc(而不是在您的编辑器或 IDE 中运行,因为这将使用与 PATH 中的 tsc 不同版本号的私有实例 tsc ) 看看它是否在那里工作 - 如果没有,tsc --version 说什么?
  • Version 3.9.6
  • 这是在一个 Vue 项目中。我没有玩过配置(webpack、babel 或 ts),所以它有“最新的”(大约 1 个月前)转换插件,我期待它能够工作。作为记录,compilerOptions 说:target: "esnext", module: "esnext", ..., lib: ["esnext", "dom", "dom.iterable", "scripthost" ].
  • @tao: 哪些转换插件?
【解决方案2】:

您的 TypeScript 代码是有效的,并且至少在 TS 3.9.2 中已正确转换为 JS。它似乎是一个 jsfiddle 错误或 TS 错误?他们在您链接到的 jsfiddle 中使用 TS 1.7.3,您可以通过在 devtools 控制台中执行 ts.version 来验证。

我在他们用来将 TS 转换为 JS 的脚本中添加了一个日志断点,如下所示:

var transpiled = ts.transpile.apply(ts, [param[0], param[1], "filename", diagnostics]);
new Function(transpiled)();

记录transpiled 变量表明代码已转换为:

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 }))));

注意箭头函数被转换为:

function ([label, fileName]) ({ [label]: fileName })))

这当然是无效的。我建议你在 vscode 或 ts-node 中使用 Quokka 之类的东西,如果你想在本地游乐场尝试一些东西而无需设置东西,但你至少可以控制你正在尝试的 TS 版本。

【讨论】:

  • 欢迎来到Stack Overflow,Eddy,感谢您抽出宝贵时间回答。恐怕在添加时,您的回答并没有带来任何新的东西。它陈述的所有内容都已在问题下方的讨论或先前的“答案”中进行了概述(就像您的一样,它没有回答实际问题:什么是/曾经是(技术上)根本原因?)。另外,我使用的不是 VSCode,而是基于 IntelliJ 的 IDE(具有强大的 Typescript 工具)。
猜你喜欢
  • 2014-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-26
  • 2010-12-29
  • 1970-01-01
  • 2021-08-05
  • 2011-11-14
相关资源
最近更新 更多