react-jsonschema-form icon indicating copy to clipboard operation
react-jsonschema-form copied to clipboard

Cannot rely on typing for custom components.

Open hickscorp opened this issue 2 years ago • 4 comments

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?

hickscorp avatar May 08 '23 22:05 hickscorp

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 avatar May 09 '23 20:05 heath-freenome

@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 avatar May 11 '23 14:05 hickscorp

@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.

heath-freenome avatar May 11 '23 18:05 heath-freenome

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.

stale[bot] avatar Aug 11 '24 03:08 stale[bot]

This issue was closed because of lack of recent activity. Reopen if you still need assistance.

stale[bot] avatar Sep 11 '24 00:09 stale[bot]