Language-tools: Typoskript-Kontrollfluss innerhalb von if / {# if} funktioniert bei Verwendung von $ store nicht

Erstellt am 27. Aug. 2020  ·  15Kommentare  ·  Quelle: sveltejs/language-tools

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.

Fixed bug

Hilfreichster Kommentar

In der Zwischenzeit kann die Neuzuweisung zu einer lokalen Variablen eine Problemumgehung sein:

$: storeValue = $store

Alle 15 Kommentare

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.

Screen Shot 2020-09-03 at 9 03 34

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:

  • Das Umbenennen der Geschäftsvariablen sollte danach noch funktionieren
  • Der Fehler vom Typ "$ x ist kein Geschäft" sollte danach immer noch funktionieren

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öglicherweise null , sodass der Fehler korrekt ist. Sie müssen nach test 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ü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.

Es funktioniert für mich! Ich kann meinen Neuzuweisungs-Hack entfernen. Vielen Dank.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen