sveltestore

Type Check the Item in #each loop in svelte


I have a store defined in the store/stores.js as follows:

import { get, writable, readable } from "svelte/store";
export const labelStore = writable([])

The labels in my program all of type LabelType defined as follows:

type LabelType = {
    imageURL: string;
    frameNumber: number;
    pointX: number;
    pointY: number;
    action: "contact" | "detach";
    agent: "hand" | "object";
}

In my main section I have a loop that iterates over the labels in the LabelStore and present them to the screen, as follows:

<main>
    {#each $labelStore as lbl, index}
        <div>Index {index}</div>
        <div>Image URL: {lbl.imageURL}</div>
        <div>Frame #: {lbl.frameNumber}</div>
        <div>Point x: {lbl.pointX}</div>
        <div>Point y: {lbl.pointY}</div>
        <div>Agent: {lbl.agent}</div>
        <div>Action: {lbl.action}</div>
        <div>--------------------------------</div>
    {/each}
</main>

The problem I'm facing is an error telling me that the attributes I'm trying to acces do not exist:

Property 'imageURL' does not exist on type 'never'.ts(2339)
Property 'frameNumber' does not exist on type 'never'.ts(2339)
...

I'd like to cast the lbl inside the #each loop to <LabelType>. What is the correct way to do it?

Thanks in advance


Solution

  • TypeScript is not able to infer the type of the array passed to writable since it's an empty array. To explicitly give it a type, you can pass the type as a type argument to writable:

    type LabelType = {
        imageURL: string;
        frameNumber: number;
        pointX: number;
        pointY: number;
        action: "contact" | "detach";
        agent: "hand" | "object";
    }
    
    export const labelStore = writable<LabelType[]>([])