Wie erstelle ich einen Typ, der jeden Schlüssel eines Schemas enthalten muss, aber auch andere Schlüssel enthalten kann?JavaScript

Javascript-Forum
Guest
 Wie erstelle ich einen Typ, der jeden Schlüssel eines Schemas enthalten muss, aber auch andere Schlüssel enthalten kann?

Post by Guest »

Ich versuche, eine React-Komponente zu erstellen, um Formulare mithilfe von Zod und React-Hook-Form dynamisch zu erstellen, zu verwalten und zu rendern. Im Wesentlichen gibt es eine Registrierung der Eingabekomponenten und des von ihr verarbeiteten Zod-Typs, die zum Erstellen eines Konfigurationsobjekts verwendet wird, in dem der Benutzer das Zod-Schema und dann die Feldkonfigurationen angibt, die automatisch kompatible Komponenten aus der Registrierung vorschlagen.Das funktioniert alles großartig, aber ich bin auf ein Problem gestoßen, als ich versucht habe, dem Benutzer die Möglichkeit hinzuzufügen, Nicht-Feld-Komponenten anzugeben, die im Einklang mit den Feldkomponenten gerendert werden sollen, beispielsweise ein Widget zur Visualisierung eines Felds , direkt über einem bestimmten Feld. Dies ist der Konfigurationstyp:

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;
};
Die FieldItemConfig verfügt über einen Feldtyp, der aus Registrierungskomponenten auswählt, die für den Zod-Typ des Felds gelten, und ein Props-Feld für optionale Props. Das NonFieldElement gibt Requisiten eines beliebigen Typs und eine beliebige Reaktionskomponente an.
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 ;
}
}
TypeScript beschwert sich über die Komponente im else-Block und sagt, dass „die Komponente im Typ (Typ für FieldItemConfig) nicht vorhanden ist“.
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?

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post