Skip to content

Handling Record<string, string> Input with Superforms #447

@mpost

Description

@mpost

Description:

We are using a Zod schema with Record<string, string> to support a multi-language message. Our schema is defined as follows:

z.object({
  message: z.record(z.string()).optional(),
});

This allows inputs such as:

{
  message: {
    de: "guten tag",
    en: "good day",
    fr: "bonjour",
    // ...
  }
}

Our goal is to build a custom component that accepts the message key as input and displays the various messages within a single component. While this works fine for single values (e.g., message: "hello"), we are unable to correctly pass the Record based message to a component.

Current Implementation:

Here is our current code, which does not have the correct type for the field value. Typically, you would use FormPathLeaves<T> directly, but that is not possible with Record. Additionally, the code has incorrect types for the $errors and $value stores, as it treats them as singular values.

<script lang="ts" context="module">
  type T = Record<string, unknown>;
</script>

<script lang="ts" generics="T extends Record<string, unknown>">
  import MultiLanguageTextarea from '$lib/components/form/MultiLanguageTextarea.svelte';
  import { formFieldProxy, type SuperForm, type FormPathLeaves } from 'sveltekit-superforms';
  import type { Writable } from 'svelte/store';

  export let form: SuperForm<T>;
  export let field: string;

  $: leaves = field as FormPathLeaves<T>
  $: ({ value, errors } = formFieldProxy(form, leaves))
</script>

<MultiLanguageTextarea bind:value={$value} errors={$errors} {...$$restProps} />

Question:

What is the correct way to handle a Record<string, string> based input when using Superforms?

Expected Behavior:

We need a solution that correctly types the field value and ensures the $errors and $value stores are correctly typed as Record<string, string>.

Any guidance or examples on how to achieve this would be greatly appreciated. Thank you!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions