arktypea
arktype8mo ago
Simon

Can the JSON Schema be typed automatically?

I'm trying to use the generated JSON Schema inside forms in order to provide useful information to users, such as if the field is required/optional, if there is a max length limit, etc..

I'm using this schema:

export const schema = type({
    uid: type("string").configure({
        message: () => i18n._("The episode UID is required."),
    }),
    title: type("string > 2").configure({
        message: (ctx) =>
            ctx.data
                ? i18n._("The episode title must be at least 3 characters long.")
                : i18n._("The episode title is required."),
    }),
    summary: type("string <= 4000")
        .configure({
            message: () =>
                i18n._("The summary must be less than 4000 characters long."),
        })
        .optional(),
});

const jsonSchema = schema.toJsonSchema()


The JSON Schema I get, is a JsonSchema.NonBooleanBranch which is too broad and I can't really use it in TS without a lot of defensive checks and casting.

Ideally I'd like to use it like this:

<form.AppField
    name="summary"
    children={(field) => (
        <field.FormItem className="grid gap-2">
            <field.FormLabel>
                <Trans>Summary</Trans>
                {schema.required?.includes(field.name) && (
                    <span className="italic">
                        — <Trans>optional</Trans>
                    </span>
                )}
            </field.FormLabel>
            <field.FormControl>
                <field.FormTextarea />
            </field.FormControl>
            <div className="italic text-xs text-right">
                <Trans>
                    {{ count: field.state.value?.length ?? 0 }} /{" "}
                    {{
                        max: schema.properties[field.name]!.maxLength! ?? 0,
                    }}{" "}
                    characters
                </Trans>
            </div>
            <field.FormMessage />
        </field.FormItem>
    )}
/>
Was this page helpful?