sveltejsdocsvelte-5

svelte 5 - how to write JSDoc for props


I have following snippet file, in which I would like to add JSDoc in order to defines tables and table in {each} part of the code.

<script>

    import { dialog } from "../store/dialog.svelte";

    /**
     * The tables to be displayed.
     */
    let { tables } = $props();

    /**
     * Logs the ID of a table for an order.
     *
     * @function
     * @param {Object} table - The table object containing information about the order.
     * @param {number} table.id - The unique identifier for the table.
     * @param {string} table.name - The name of the table.
     * @returns {void}
    */
    function getOrder(table){
        dialog.open = true;
        dialog.title = `${table.name} Order`;
    }

</script>

{#each tables as table}
    <div class="card bg-base-100 shadow-xl">
        <div class="card-body py-2 px-1">
            <h2 class="card-title">{table.name}
                <sup class="text-sm">({table.seats}<i class="fa-solid fa-chair"></i>)</sup>

                {#if table.order }
                <sup>
                    <button class="bg-green-500 text-white p-2 rounded-full
                    transition duration-300 ease-in-out transform hover:scale-105 animate-pulse"
                    ></button>
                </sup>
                {/if}
            </h2>

            <div class="card-actions justify-end">
                <button class="btn btn-info btn-xs"
                onclick="{() => getOrder(table)}">Show Order</button>
            </div>
        </div>
    </div>
{/each}

This is where the props are passed:

<script>
    import { tables } from "../store/tables.svelte";
    import Table from "../snippets/Table.svelte";

</script>

<nav id="mainNav">
    <h3>Tables</h3>
    <div class="divider"></div>

    <div class="border grid grid-cols-4 gap-4 justify-between py-5 px-2 bg-gray-100">
        <Table tables={tables.tables}></Table>
    </div>


</nav>

This is store for the tables:

import { user } from "./user.svelte"

function createTables(){

    /**
     * @typedef {Object} Waiter
     * @property {number} id
     */

    /**
     * @typedef {Object} table
     * @property {number} id
     * @property {string} name
     * @property {number|null} seats
     * @property {null|Object} order
     * @property {Waiter} waiter
     */


    /**
     * @type {Array.<table>} tables
     */
    let tables = $state([])

    let userTables = $derived(() => {

        return tables.filter(table => {
            return +user.currentUser?.id === +table.waiter?.id
        })

    })

    let userTablesFree = $derived(() => {

        return tables.filter(table => {
            return +user.currentUser?.id === +table.waiter?.id &&
            table.order === null
        })

    })

    let userTablesUsed = $derived(() => {

        return tables.filter(table => {
            return +user.currentUser?.id === +table.waiter?.id &&
            table.order !== null
        })

    })

    let otherTablesFree = $derived(() => {

        return tables.filter(table => {
            return +user.currentUser?.id !== +table.waiter?.id &&
            table.order === null
        })

    })

    let otherTablesUsed = $derived(() => {

        return tables.filter(table => {
            return +user.currentUser?.id !== +table.waiter?.id &&
            table.order !== null
        })

    })

    return {
        get tables(){
            return tables
        },
        set tables(newValue){
            tables = newValue
        },
        userTables,
        userTablesFree,
        userTablesUsed,
        otherTablesFree,
        otherTablesUsed
    }
}

export const tables = createTables()

Solution

  • You should be able to use @typedef & @type, e.g.

    /**
     * @typedef {Object} Props
     * @property {number} number A number prop.
     * @property {string} text A string prop.
     */
    
    /** @type {Props} */
    const { number, text } = $props();
    

    If you don't declare the types in a separate .d.ts file (which I would recommend for more complex types), you can use import statements in the type. E.g.

    /**
     * @typedef {Object} Props
     * @property {typeof import('./tables.svelte.js').tables} tables Tables
     */
    

    Also: I would not recommend using global state (export const tables = ...), especially if you have SSR, then this is a privacy/security risk.