Language-tools: Le flux de contrôle Typescript à l'intérieur de if / {# if} ne fonctionne pas lors de l'utilisation de $ store

Créé le 27 août 2020  ·  15Commentaires  ·  Source: sveltejs/language-tools

Lorsque vous avez un magasin défini comme suit:

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

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

Et puis dans votre modèle vous écrivez:

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

Ensuite, le vérificateur dactylographié se plaint à juste titre Object is possibly 'null' . Ensuite, j'espérais que je pourrais faire disparaître cette erreur en faisant ceci:

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

Mais cela n'a aucun effet. Quel genre de logique. Je comprends que dactylographié peut ne pas comprendre que c'est une instruction if.

Je peux imaginer que ce ne serait en fait pas trivial à mettre en œuvre, mais je ne sais pas, ce serait vraiment bien.

Fixed bug

Commentaire le plus utile

En attendant, la réattribution à une variable locale peut être une solution de contournement:

$: storeValue = $store

Tous les 15 commentaires

Le problème est que

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

obtient (par nous, via svelte2tsx , pour toute la bonté intellisense) traduit en

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

Comme vous pouvez le voir, l'accès au magasin est traduit en une fonction __sveltets_store_get , et le flux de contrôle de TS ne peut donc pas déterminer que ce n'est pas indéfini / nul. Pour résoudre ce problème, nous aurions besoin de traduire cela de manière à ce que le premier __sveltets_store_get soit affecté à une variable, qui est ensuite utilisée dans la portée if.

D'accord, cela semble faisable? 😇

je pense que oui

Juste un commentaire pour dire que j'ai rencontré le même problème en essayant d'ajouter la prise en charge de Typescript au modèle Sapper standard:

De mon message sur le canal Discord #sapper:

J'ai une question:

La prise en charge de Svelte Typescript s'étend-elle aux blocs HTML comme {#each cat as cats} ?

La capture d'écran provient de svelte-check après avoir activé Typescript pour le modèle Sapper standard.

Screen Shot 2020-09-03 at 9 03 34

Voici l'extrait de code pertinent de 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>

Et les erreurs associées de svelte-check (même avec strict: false dans 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}

Je ne peux pas dire quel est le problème quand je ne connais pas le type de posts . Mais vous devez probablement faire une assertion de type à la variable posts dans la balise de script afin que la publication ne soit pas inconnue.

Tant que la liste de chaque bloc implémente l'interface ArrayLike, elle devrait pouvoir en déduire le type d'élément.

En attendant, la réattribution à une variable locale peut être une solution de contournement:

$: storeValue = $store

Points à garder à l'esprit lors de l'implémentation de cela en extrayant la valeur de magasin dans une variable:

  • Renommer la variable de magasin devrait toujours fonctionner après
  • L'erreur de type "$ x n'est pas un magasin" devrait toujours fonctionner par la suite

Je rencontre le même problème, mais sans magasin.

Cas de test simple:

<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}

Sur la ligne {#if test.author} , l'erreur "L'objet est peut-être nul".

Est-ce le même problème ou un bogue différent?

En mode strict, c'est un comportement correct, vous avez tapé test comme étant probablement null , donc l'erreur est correcte. Vous devez d'abord vérifier test pour avoir été défini.

En mode strict, c'est un comportement correct, vous avez tapé test comme peut-être commencer null , donc l'erreur est correcte. Vous devez d'abord vérifier test pour avoir été défini.

Il y a un {#if test} avant cela.

Oups, a répondu trop rapidement. Oui, c'est un problème différent, pourriez-vous ouvrir un autre ticket pour cela?

Bien sûr. Je voulais juste m'assurer que ce n'est pas un double avant de l'ouvrir :)

Bonjour à tous! Des mises à jour sur celui-ci?

Cela devrait être corrigé avec l'extension VS Code Svelte version 104.4.4 et svelte-check version 1.1.36. Notez que pour svelte-check vous avez également besoin de TypeScript 4.2 ou version ultérieure.

S'il vous plaît laissez-moi savoir si cela fonctionne comme prévu maintenant. Il y a toujours des problèmes de flux de contrôle sans rapport avec l'utilisation du magasin, ceux-ci sont suivis dans # 619.

Cela devrait être corrigé avec l'extension VS Code Svelte version 104.4.4 et svelte-check version 1.1.36. Notez que pour svelte-check vous avez également besoin de TypeScript 4.2 ou version ultérieure.

S'il vous plaît laissez-moi savoir si cela fonctionne comme prévu maintenant. Il y a toujours des problèmes de flux de contrôle sans rapport avec l'utilisation du magasin, ceux-ci sont suivis dans # 619.

Ça marche pour moi! Je peux supprimer mon piratage de réassignation. Merci beaucoup.

Cette page vous a été utile?
0 / 5 - 0 notes