react-jsonschema-form
react-jsonschema-form copied to clipboard
Cannot rely on typing for custom components.
We've created a few custom components to be rendered via their mappings in a uiSchema. For example:
...
export const MultiSelect = ({ value, schema, onChange }: WidgetProps<any, any>) => {
return (
<Select
className="FastEdit-MultipleSelect"
mode="multiple"
options={stringsToOptionTypes((schema.items?.enum || []) as ReadonlyArray<string>)}
value={stringsToOptionTypes(value as ReadonlyArray<string>)}
onChange={onChange}
/>
);
};
The part that we really don't understand is how to type the WidgetProps generic 2nd argument. It seems to want a JSONSchema fragment - but we have no clue how to get it right.
If we omit the type, the problem is that schema.items.enum isn't defined - because the compiler has no clue about the underlying specialization of type S in WidgetProps. However, we know it's there - because a console.log(schema) gives us:
{
"type": "array",
"items": {
"type": "string",
"enum": [
"Pre-seed",
"Seed",
"Growth",
"Scale",
"Large Enterprises"
],
"minItems": 1
}
}
Unfortunately without knowing how to type WidgetProps, the whole idea of keeping type safety guarantees becomes kind of useless.
The only way we found to have a way to compile with a minimum of basic safety is an absolutely horrendous idea:
export const MultiSelect = ({ value, schema, onChange }: WidgetProps<any, JSONSchema7>) => {
return (
<Select
className="FastEdit-MultipleSelect"
mode="multiple"
options={stringsToOptionTypes(((schema.items as JSONSchema7).enum || []) as ReadonlyArray<string>)}
value={stringsToOptionTypes(value as ReadonlyArray<string>)}
onChange={onChange}
/>
);
};
Any idea please?
What if you just used WidgetProps without types. The defaults provided without types are <any, StrictRJSFSchema, any>. Note (StrictRJSFSchema is currently just an alias to JSONSchema7)
@heath-freenome Thanks a lot for helping.
So - we tried that. Not specifying any type works, but it shouldn't - ideally, our custom widgets should be generic. Right now, it looks like this:
const widgetsRegistry: RegistryWidgetsType = {
TagsEditor,
...
StageMultiSelect: EnumMultiSelect(Stages),
...
}
Instead, it should look like:
const widgetsRegistry: RegistryWidgetsType = {
TagsEditor,
...
StageMultiSelect: MultiSelect<SubSchemaForStages or whatever>,
...
}
For this to work, the Form component should work closely with the type of our schema - not duck-typing it or down-typing it to JSONSchema7. So that internally, Form could verify that the custom widgets / templates are appropriate for the schema fragment they apply to... Does that make sense?
But IMO the main problem here is that we should be able to have typing. What's the point of having typing on WidgetProps otherwise? In our mind, we would be able to have our widget registered in our factories using a schema fragment (subset of our main schema), so that the widget itself could be a generic with proper types at compile time.
Isn't that what RJSF is about - or am I mistaken?
@hickscorp See my comment in the other issue related to my asking AJV to export their types without needing to include the AJV implementation library itself.
This issue has been automatically marked as possibly close because it has not had recent activity. It will be closed if no further activity occurs. Please leave a comment if this is still an issue for you. Thank you.
This issue was closed because of lack of recent activity. Reopen if you still need assistance.