Wenn Sie ein Geschäft wie folgt definiert haben:
import { readable, Readable } from "svelte/store"
const post: Readable<Post|null> = readable(null, /* some code that loads the post asynchronously */)
Und dann schreiben Sie in Ihre Vorlage:
<h1>{$post.title}</h1>
Dann beschwert sich der Typoskript-Prüfer zu Recht über Object is possibly 'null'
. Dann hatte ich gehofft, dass ich diesen Fehler dadurch verschwinden lassen könnte:
{#if $post !== null}
<h1>{$post.title}</h1>
{/if}
Das hat aber keinerlei Auswirkungen. Welche Art macht Sinn. Ich verstehe, dass Typoskript möglicherweise nicht versteht, dass dies eine if-Anweisung ist.
Ich kann mir vorstellen, dass dies eigentlich nicht trivial zu implementieren wäre, aber ich weiß nicht, es wäre wirklich schön.
Das Problem ist, dass
{#if $post !== null}
<h1>{$post.title}</h1>
{/if}
wird (von uns durch svelte2tsx
für all die Intellisense-Güte) übersetzt in
if (__sveltets_store_get(post) !== null){<>
<h1>{__sveltets_store_get(post).title}</h1>
</>}
Wie Sie sehen können, wird der Geschäftszugriff in eine __sveltets_store_get
-Funktion übersetzt, und der Kontrollfluss von TS kann daher nicht feststellen, dass dies nicht undefiniert / null ist. Um dies zu beheben, müssten wir dies so übersetzen, dass die ersten __sveltets_store_get
einer Variablen zugewiesen werden, die dann im if-Bereich verwendet wird.
Okay, das klingt machbar? 😇
Ich glaube schon
Nur ein Kommentar, der besagt, dass ich beim Versuch, der Standard-Sapper-Vorlage Typescript-Unterstützung hinzuzufügen, auf dasselbe Problem gestoßen bin:
Aus meinem Beitrag auf dem Discord #sapper-Kanal:
Ich habe eine Frage:
Erweitert sich die Unterstützung von Svelte Typescript auf HTML-Blöcke wie {#each cat as cats}
?
Der Screenshot stammt von svelte-check, nachdem ich Typescript für die Standard-Sapper-Vorlage aktiviert habe.
Hier ist das relevante Code-Snippet von 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>
Und die damit verbundenen Fehler von svelte-check (auch mit strict: false
in 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}
Ich kann nicht sagen, wo das Problem liegt, wenn ich den Typ von posts
nicht kenne. Aber Sie müssen wahrscheinlich eine Typzusicherung für die Variable posts
im Skript-Tag vornehmen, damit der Beitrag nicht unbekannt ist.
Solange die Liste in jedem Block die ArrayLike-Schnittstelle implementiert, sollte sie in der Lage sein, daraus einen Elementtyp abzuleiten.
In der Zwischenzeit kann die Neuzuweisung zu einer lokalen Variablen eine Problemumgehung sein:
$: storeValue = $store
Beachten Sie Folgendes, wenn Sie dies implementieren, indem Sie den Speicherwert in eine Variable extrahieren:
Ich habe das gleiche Problem, aber ohne Speicher.
Einfacher Testfall:
<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}
In Zeile {#if test.author}
wird der Fehler "Objekt ist möglicherweise null" angezeigt.
Ist es das gleiche Problem oder ein anderer Fehler?
Im strengen Modus ist dies ein korrektes Verhalten. Sie haben test
als möglicherweise null
eingegeben, sodass der Fehler korrekt ist. Sie müssen nach test
suchen, um zuerst definiert zu werden.
Im strengen Modus ist dies ein korrektes Verhalten. Sie haben
test
eingegeben, um möglicherweisenull
, sodass der Fehler korrekt ist. Sie müssen nachtest
suchen, um zuerst definiert zu werden.
Davor gibt es einen {#if test}
Scheck.
Hoppla, habe zu schnell geantwortet. Ja, das ist ein anderes Problem. Könnten Sie dafür ein anderes Ticket eröffnen?
Natürlich. Ich wollte nur sicherstellen, dass es kein Duplikat ist, bevor ich es öffne :)
Hallo zusammen! Irgendwelche Updates zu diesem?
Dies sollte mit der VS Code Svelte-Erweiterung Version 104.4.4 und svelte-check
Version 1.1.36 behoben werden. Beachten Sie, dass Sie für svelte-check
auch TypeScript 4.2 oder höher benötigen.
Bitte lassen Sie mich wissen, ob es jetzt wie erwartet funktioniert. Es gibt immer noch Probleme mit dem Kontrollfluss, die nicht mit der Speichernutzung zusammenhängen. Diese werden in # 619 nachverfolgt.
Dies sollte mit der VS Code Svelte-Erweiterung Version 104.4.4 und
svelte-check
Version 1.1.36 behoben werden. Beachten Sie, dass Sie fürsvelte-check
auch TypeScript 4.2 oder höher benötigen.Bitte lassen Sie mich wissen, ob es jetzt wie erwartet funktioniert. Es gibt immer noch Probleme mit dem Kontrollfluss, die nicht mit der Speichernutzung zusammenhängen. Diese werden in # 619 nachverfolgt.
Es funktioniert für mich! Ich kann meinen Neuzuweisungs-Hack entfernen. Vielen Dank.
Hilfreichster Kommentar
In der Zwischenzeit kann die Neuzuweisung zu einer lokalen Variablen eine Problemumgehung sein: