Я пытаюсь создать компонент реагирования для динамического создания, управления и рендеринга форм с использованием zod и React-Hook-Form. По сути, существует реестр входных компонентов и обрабатываемых им типов zod, который используется для создания объекта конфигурации, в котором пользователь указывает схему zod, а затем полей конфигурации, которые автоматически предлагают совместимые компоненты из реестра. Все это прекрасно работает, но я столкнулся с кошмарной проблемой при попытке добавить пользователю возможность указывать компоненты, не являющиеся полем, для рендеринга в соответствии с компонентами поля, например какой-то виджет для визуализации поля, прямо над ним. определенное поле. Это тип конфигурации:
Код: Выделить всё
export type ItemsConfig =
// A) Required field items for keys in the schema
{
[K in keyof Z["shape"] & string]: {
type: "field item";
config: FieldItemConfig;
};
} & {
// B) Optional non-field items for any other string keys
[K in Exclude]?: {
type: "non-field item";
config: NonFieldElement;
};
};
export type FormStageConfig<
R extends FormItemRegistry,
Z extends ZodObject,
> = {
title?: string;
description?: string;
schema: Z;
items: ItemsConfig;
};
FieldItemConfig имеет тип поля, который выбирает из компонентов реестра, применимых к типу поля zod, и поле реквизитов для дополнительных реквизитов. NonFieldElement указывает реквизит любого типа и любой реагирующий компонент. Это работает так, как я хочу при определении конфигурации, до тех пор, пока не будут определены все элементы поля, после чего машинописный скрипт внезапно меняет свое мнение и решает, что тип для первого определенного элемента поля на самом деле должен быть элементом, отличным от поля... Кроме того, в компоненте динамического рендеринга машинописный текст сворачивает тип полей элементов, делая их только FieldItemConfigs. В этом коде
Код: Выделить всё
for (const itemKey of itemKeys) {
const item = items[itemKey];
if (item.type === "field item") {
// Get props and field type from config
const { type, props } = item.config;
// Get Field type component from registry
const { component: Component } = registry[type];
return ;
// Construct non-field component
} else {
const { component: Component, props } = item.config;
return ;
}
}
typescript жалуется на компонент в блоке else, говоря, что «компонент не существует по типу (тип для FieldItemConfig)». Я думаю, что изменение типа элементов на массив, вероятно, сработает, но тогда я не думаю, что смогу обеспечить соблюдение ограничения, согласно которому массив содержит все поля в схеме. Я попробовал несколько других определений для ItemsConfig, и кажется, что при использовании [K в строке] вместо исключения для необязательных компонентов, не являющихся полем, логика рендеринга работает, и машинописный скрипт может определить, что поля, в которых тип != элемент поля, являются элементы, не являющиеся полями, но та же проблема возникает в определении конфигурации, где, как только все поля определены, он внезапно заявляет, что вместо этого они должны быть элементами, не являющимися полями. Я не очень хорошо разбираюсь в реализации машинописного текста, но я часами ходил взад и вперед с Chat gpt, и он не мог решить мою проблему, поэтому я предполагаю, что это, по крайней мере, не простой шаблон машинописного текста, который мне просто не хватает. Я также попробовал протестировать это с гораздо более простыми типами для полевых и не полевых конфигураций, что дало те же результаты, поэтому я относительно уверен, что здесь нет какой-то проблемы с базовыми типами. Неужели просто невозможно указать объект таким образом? Если нет, есть ли способ с помощью машинописного текста обеспечить, чтобы массив содержал определенный набор объектов, соответствующих ключам схемы? Спасибо
Подробнее здесь:
https://stackoverflow.com/questions/793 ... ma-but-may