Language-tools: Each Block Typing Issue

Created on 3 Jan 2021  ·  5Comments  ·  Source: sveltejs/language-tools

I'm trying to iterate over a properties values by using {#each...}, and I have two typings (this is a TypeScript project) in my Svelte component.

<script lang="ts">
    import Transition from './Transition/Transition.svelte';

    type Options = { text: string, value?: string }[];
    type OptionsGroup = Options[];

    export let options: Options | OptionsGroup = [];
</script>

{#each options as option}
    <div>example</div>
{/each}

I would expect the type of option in the each statement to be Options | OptionsGroup but VS Code is giving me an error saying:

Argument of type 'Options | OptionsGroup' is not assignable to parameter of type 'ArrayLike<{ text: string; value?: string; }>'.

I'm unsure of what exactly is going wrong as the build and dev tasks are working fine with no errors at all, it only seems to be an issue with VS Code.

System:

  • OS: Manjaro (Linux)
  • IDE: VSCode
  • Plugin/Package: Svelte for VSCode
bug question

All 5 comments

I also found a strange bug with {#each}.

Smallest repro possible:

<script lang="ts">
  let data: { name: string } | null = null,
    someArr = [1, 2, 3];
</script>

{#if data}
  <!-- Works fine -->
  {data.name}
  {#each someArr as _}
    <!-- Highlights an error! -->
    {data.name}
  {/each}
{/if}

Mac, VS Code, running the latest plugin. I have a gut feeling it is somewhat connected to this issue.

Proof of bug

@dkzlv that's #619

I fear this is not possible to fix on our side, it seems it's a TypeScript issue. You would get the same error when you do this:

function each<T>(
    array: ArrayLike<T>, // or T[], doesnt matter for the error
    callbackfn: (value: T, index: number) => any
): any{ /* doesnt matter */ };

each(options, a => a); // The same TS error

that each function is basically what is used to type-check the each-block. I did not find a way to silence the error without losing type safety.

You can do this instead. I think I have this typescript error before and got it works by trying some random combination lol

<script lang="ts">
  type Option = { text: string, value?: string };
  type OptionsGroup = Option[];

  export let options: Array<Option | OptionsGroup> = [];
</script>

{#each options as option}
  <div>example</div>
{/each}

Edit:
Noted these two types are not the same, but you probably don't care about the difference most of the time. If you do care, you probably need to write some custom type guard to cast it.

Thank you for the clarification, I've amended my typings as recommend and that has pretty much solved it.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

maximedupre picture maximedupre  ·  5Comments

non25 picture non25  ·  5Comments

PatrickG picture PatrickG  ·  3Comments

matthewmueller picture matthewmueller  ·  3Comments

arxpoetica picture arxpoetica  ·  3Comments