Language-tools: 销毁 $store 值时出现意外错误

创建于 2020-08-11  ·  6评论  ·  资料来源: sveltejs/language-tools

描述错误
value$store的属性并且$store是 Svelte 商店时,语句$: ({ value } = $store);是有效语法。 它的行为类似于正常的解构,并且对存储更新具有反应性。 这会在lang="ts"时产生错误。

# App.svelte
------------
<script lang="ts">
  import data from "./store";
  $: ({ count } = $data);
</script>
jd:/svelte-playground $ yarn svelte-check                                                                                                                                                                                                                      [0:30]
yarn run v1.22.4
warning package.json: No license field
$ /home/jd/Projects/svelte-playground/node_modules/.bin/svelte-check

Loading svelte-check in workspace: /home/jd/Projects/svelte-playground
Getting Svelte diagnostics...
====================================

/home/jd/Projects/svelte-playground/src/App.svelte:3:9
Error: No value exists in scope for the shorthand property 'count'. Either declare one or provide an initializer. (ts)
;
  $: ({ count } = $data

====================================
svelte-check found 1 error and 0 warnings
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

再现
1) 从这个 REPL 开始:链接
2)下载并为项目添加TS支持:链接
3) 通过将lang="ts"<script>开头标记来修改App.svelte 。 (见上面的片段)
4) 运行svelte-check

预期行为
这是有效的 Svelte/JS 语法,他的代码运行良好。 它不应该产生类型检查器错误。

截图
如果适用,请添加屏幕截图以帮助解释您的问题。
image

系统(请填写以下信息):

  • 操作系统:Windows
  • IDE:VSCode(Windows-Linux 子系统)
  • 插件/包:

    • VSCode 的 Svelte

    • 细长检查

    • @tsconfig/svelte

Fixed bug

所有6条评论

解决方法
不要在 Typescript 中对 Svelte 存储使用解构。 这不是理想的,但不是阻滞剂。 一次解构多个属性时,它就不那么简洁了。
REPL:链接

# App.svelte
------------
<script lang="ts">
  import data from "./store";
  $: count = $data;
</script>

当然,您始终可以直接在 DOM 中引用 store 值来查看响应式更新。

从输入

<script lang="ts">
  import data from "./store";
  $: ({ count } = $data);
</script>

<main>
  <h1>Count (inline): {$data.count}</h1>
  <h1>Count (reactive destructure): {count}</h1>
    <button on:click={() => data.update(c => ({count: c.count + 1}))}>
    Increment
  </button>
</main>

svelte2tsx生成输出:

<></>;
import data from "./store";
function render() {


  ;() => {$: ({ count } = __sveltets_store_get(data));}
;
() => (<>

<main>
  <h1>Count (inline): {__sveltets_store_get(data).count}</h1>
  <h1>Count (reactive destructure): {count}</h1>
    <button onclick={() => data.update(c => ({count: c.count + 1}))}>
    Increment
  </button>
</main> </>);
return { props: {}, slots: {}, getters: {}, events: {} }}

export default class extends createSvelte2TsxComponent(__sveltets_partial(render)) {
}

问题在于$ -assignment 被包装在一个函数中,因此该值不存在于其范围之外。

我们可能需要检查 svelte 编译器如何确定它何时应该声明一个变量,看看我们是否错过了其他情况

问题是 ts AST 分析。 如果它是一个二进制表达式,它只执行let x = ...转换,但在这种情况下,它是一个包含在括号表达式中的二进制表达式。

编辑:我正在解决这个问题 - 所有这些 if-then-also-think-of-this-corner-case-检查让我的思绪变得模糊 😄

是的,很多事情需要改变。 我将创建一个 PR 草案,以便您可以查看我的当前状态。

此页面是否有帮助?
0 / 5 - 0 等级