Code: Select all
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;
};
Das funktioniert so, wie ich es beim Definieren der Konfiguration haben möchte, bis alle Feldelemente definiert sind, und dann TypeScript ändert plötzlich seine Meinung und entscheidet, dass der Typ für das erste definierte Feldelement tatsächlich ein Nicht-Feldelement sein sollte.
Außerdem reduziert TypeScript in der dynamischen Rendering-Komponente den Typ für die Elementfelder auf nur FieldItemConfigs sein. In diesem Code
Code: Select all
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 ;
}
}
Das denke ich Das Ändern des Elementtyps in ein Array würde wahrscheinlich funktionieren, aber dann glaube ich nicht, dass ich die Einschränkung erzwingen könnte, dass das Array jedes Feld im Schema enthält. Ich habe mehrere andere Definitionen für ItemsConfig ausprobiert und es scheint, dass bei Verwendung von [K in string] anstelle von Exclude für die optionalen Nichtfeldkomponenten die Rendering-Logik funktioniert und TypeScript herausfinden kann, welche Felder sich in den Feldern vom Typ != field befinden Nicht-Feld-Elemente, aber das gleiche Problem tritt in der Konfigurationsdefinition auf, wo, sobald alle Felder definiert sind, plötzlich behauptet wird, sie sollten stattdessen Nicht-Feld-Elemente sein.
Ich habe auch versucht, dies mit zu testen viel einfachere Typen für Feld und Nicht-Feld configs, was die gleichen Ergebnisse liefert, daher bin ich relativ sicher, dass es kein Problem mit den zugrunde liegenden Typen dort ist. Ist es einfach nicht möglich, ein Objekt auf diese Weise anzugeben? Wenn nicht, gibt es eine Möglichkeit, über TypeScript zu erzwingen, dass ein Array einen bestimmten Satz von Objekten enthalten muss, die den Schlüsseln des Schemas entsprechen?