#How to use a Set in default values?

13 messages · Page 1 of 1 (latest)

dire shadow
#

I am using Select from Hero UI, which uses a Set for its value. But when I do this, the schema validator types do not come out correctly. It seems they are transforming the types to be serializable, converting from Set to Array.

Here's a mini code snippet to reproduce:

import {Schema} from "effect";

export const CreateScheduleInputSchema = Schema.Struct({
    daysOfWeek: Schema.Set(Schema.Enums(DayOfWeek)).pipe(Schema.mutable),
});

const form = useAppForm({
    defaultValues: {
        daysOfWeek: new Set(),
    },
    validators: {
        // The types are wrong here!
        onSubmit: Schema.standardSchemaV1(CreateScheduleInputSchema),
    },
});

Is there something I am missing?

#

Here's the error

dire shadow
#

One way I solved this is to control the type so only arrays are set on the form instead of sets


export function FormSelect<T extends object>(props: SelectProps<T>) {
  const field = useFieldContext<SharedSelection | string | number>();
  const isInvalid = !field.state.meta.isValid;

  return (
    <Select<T>
      name={field.name}
      onBlur={field.handleBlur}
      errorMessage={field.state.meta.errors?.[0]?.message}
      isInvalid={isInvalid}
      {...props}
    />
  );
}

export function FormSelectSingle<T extends object>(props: SelectProps<T>) {
  const field = useFieldContext<string | number>();

  return (
    <FormSelect<T>
      selectionMode="single"
      selectedKeys={new Set([field.state.value])}
      onSelectionChange={(value) => field.handleChange([...value][0])}
      {...props}
    />
  );
}

export function FormSelectMultiple<T extends object>(props: SelectProps<T>) {
  const field = useFieldContext<Array<string | number>>();

  return (
    <FormSelect<T>
      selectionMode="multiple"
      selectedKeys={new Set(field.state.value)}
      onSelectionChange={(value) => field.handleChange([...value])}
      {...props}
    />
  );
}
#
import {Schema} from "effect";

export const CreateScheduleInputSchema = Schema.Struct({
    daysOfWeek: Schema.Set(Schema.Enums(DayOfWeek)).pipe(Schema.mutable),
});

export type CreateScheduleInputSchema = typeof CreateScheduleInputSchema.Type;

const form = useAppForm({
    defaultValues: {
        daysOfWeek: [],
    } as CreateScheduleInputSchema,
    validators: {
        // The types are wrong here!
        onSubmit: Schema.standardSchemaV1(CreateScheduleInputSchema),
    },
});
sand wave
#

the standard schema spec requires them to be around, but I don‘t know the syntax to get them for this library

dire shadow
#

Yeah, that's done through what I have above

typeof CreateScheduleInputSchema.Type
sand wave
dire shadow
#

That's the same as the type cast I have above:

    defaultValues: {
        daysOfWeek: [],
    } as CreateScheduleInputSchema,
sand wave
dire shadow
#

Ah, right. Here's a minimal reproduction:

export const TestSchema = Schema.Struct({
  aSet: Schema.Set(Schema.Enums(DayOfWeek)).pipe(Schema.mutable),
});

type TestSchema = typeof TestSchema.Type;

const testDefaultValues: TestSchema = {
  aSet: new Set(),
};

function TestComponent() {
  const form = useAppForm({
    defaultValues: testDefaultValues,
    validators: {
      // Types fail here!
      onSubmit: Schema.standardSchemaV1(TestSchema),
    },
    onSubmit: async ({ value }) => {
      const decodedValue = Schema.decodeUnknownSync(TestSchema)(value);
      console.log(decodedValue);
    },
  });
}