Language-tools: 使用$ store时,if / {#if}内的打字稿控制流程不起作用

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

当您具有如下定义的商店时:

import { readable, Readable } from "svelte/store"

const post: Readable<Post|null> = readable(null, /* some code that loads the post asynchronously */)

然后在模板中编写:

<h1>{$post.title}</h1>

然后打字稿检查器正确地抱怨Object is possibly 'null' 。 然后,我希望可以通过执行以下操作使该错误消失:

{#if $post !== null}
    <h1>{$post.title}</h1>
{/if}

但这没有任何作用。 哪种才有意义。 我了解打字稿可能不了解这是一个if语句。

我可以想象这实际上并不容易实现,但是我不知道,这真的很好。

Fixed bug

最有用的评论

同时,重新分配给局部变量可能是一种解决方法:

$: storeValue = $store

所有15条评论

问题是

{#if $post !== null}
    <h1>{$post.title}</h1>
{/if}

获取(通过我们,通过svelte2tsx ,以获取所有的智能感知优势)转换为

if (__sveltets_store_get(post) !== null){<>
    <h1>{__sveltets_store_get(post).title}</h1>
</>}

如您所见,商店访问权已转换为__sveltets_store_get函数,因此TS的控制流无法确定它不是未定义/为空。 要解决此问题,我们需要以将第一个__sveltets_store_get分配给一个变量的方式进行翻译,然后在if-scope中使用该变量。

好吧,这听起来可行吗? 😇

我认同

只是说一句话,当我尝试将Typescript支持添加到标准Sapper模板时遇到了相同的问题:

在Discord #sapper频道上的帖子中:

我有个问题:

Svelte Typescript支持是否扩展到{#each cat as cats}类的HTML块?

屏幕截图来自我为标准Sapper模板启用Typescript后的精巧检查。

Screen Shot 2020-09-03 at 9 03 34

这是src/routes/blog/index.svelte的相关代码段:

<ul>
    {#each posts as post}
        <!-- we're using the non-standard `rel=prefetch` attribute to
                tell Sapper to load the data for the page as soon as
                the user hovers over the link or taps it, instead of
                waiting for the 'click' event -->
        <li><a rel='prefetch' href='blog/{post.slug}'>{post.title}</a></li>
    {/each}
</ul>

以及相关的错误检查(即使strict: false中有tsconfig.json ):

/Users/paul/dev/solidrevolution_svelte-sapper/src/routes/blog/index.svelte:32:42
Error: Property 'slug' does not exist on type 'unknown'. (ts)
                waiting for the 'click' event -->
        <li><a rel='prefetch' href='blog/{post.slug}'>{post.title}</a></li>
    {/each}


/Users/paul/dev/solidrevolution_svelte-sapper/src/routes/blog/index.svelte:32:55
Error: Property 'title' does not exist on type 'unknown'. (ts)
                waiting for the 'click' event -->
        <li><a rel='prefetch' href='blog/{post.slug}'>{post.title}</a></li>
    {/each}

当我不知道posts的类型时,无法说出问题是什么。 但是您可能需要对script标记中的posts变量进行某种类型断言,以便该帖子不为人所知。

只要每个块中的列表实现ArrayLike接口,它就应该能够从中推断元素类型。

同时,重新分配给局部变量可能是一种解决方法:

$: storeValue = $store

通过将商店值提取到变量中来实现这一点时要记住的事情:

  • 重命名store变量之后仍然应该起作用
  • 之后,“ $ x不是商店”类型错误仍然应该起作用

我遇到了同样的问题,但是没有存储。

简单的测试用例:

<script lang="typescript">
    interface TestObject {
        author?: string;
    }
    export let test: TestObject | null;
</script>

{#if test}
    <div>
        {#if test.author}
            <div>Author: {test.author}</div>
        {/if}
    </div>
{/if}

{#if test.author}它显示错误“对象可能为空”。

是相同的问题还是不同的错误?

在严格模式下,这是正确的行为,您键入test可能是null ,因此错误是正确的。 您需要检查test是否先被定义。

在严格模式下,这是正确的行为,您键入test可能null开头,因此错误是正确的。 您需要检查test是否先被定义。

在此之前有{#if test}支票。

糟糕,回答得太快了。 是的,这是另一个问题,您可以为此打开另一张票吗?

当然。 只是想确保它在打开之前不是重复的:)

大家好! 对此有任何更新吗?

这应该在VS Code Svelte扩展版本104.4.4和svelte-check版本1.1.36中修复。 请注意,对于svelte-check您还需要TypeScript 4.2或更高版本。

请让我知道它现在是否按预期工作。 仍然存在与商店使用无关的控制流问题,这些问题在#619中进行了跟踪。

这应该在VS Code Svelte扩展版本104.4.4和svelte-check版本1.1.36中修复。 请注意,对于svelte-check您还需要TypeScript 4.2或更高版本。

请让我知道它现在是否按预期工作。 仍然存在与商店使用无关的控制流问题,这些问题在#619中进行了跟踪。

它为我工作! 我可以删除我的重新协助黑客。 非常感谢。

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

相关问题

UltraCakeBakery picture UltraCakeBakery  ·  14评论

illright picture illright  ·  39评论

jasonlyu123 picture jasonlyu123  ·  16评论

limitlessloop picture limitlessloop  ·  16评论

dummdidumm picture dummdidumm  ·  37评论