当您具有如下定义的商店时:
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语句。
我可以想象这实际上并不容易实现,但是我不知道,这真的很好。
问题是
{#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后的精巧检查。
这是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
通过将商店值提取到变量中来实现这一点时要记住的事情:
我遇到了同样的问题,但是没有存储。
简单的测试用例:
<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中进行了跟踪。
它为我工作! 我可以删除我的重新协助黑客。 非常感谢。
最有用的评论
同时,重新分配给局部变量可能是一种解决方法: