I'm building a form component in react using typescript that takes a 'fieldStructures' and an 'onSubmit' prop.
type FieldStructure {
type: 'text';
name: string;
label?: string;
helpText?: string;
required?: boolean;
multiline?: boolean;
} | {
type: 'date';
name: string;
label?: string;
helpText?: string;
required?: boolean;
} | {
type: 'option';
name: string;
label?: string;
helpText?: string;
required?: boolean;
options: string[];
multi?: boolean;
} | {
type: 'file';
name: string;
label?: string;
helpText?: string;
required?: boolean;
fileTypes?: string[];
}
type FieldValue <T extends FieldType = any> =
T extends 'text' ? string
: T extends 'date' ? Date | null
: T extends 'option' ? string | string[] | null
: T extends 'file' ? string | File | null
: string | string[] | Date | File | null
interface FormModalProps {
fieldStructures: FieldStructure[];
handleSubmit: (values: { [key: string]: FieldValue }) => void | Promise<void>;
}
export const FormModal: React.FC<FormModalProps> = ({
fieldStructures,
handleSubmit
}) => { ... }
This works great for just making the component but not so much for using it. I want the type of the values parameter to rely on what is passed to the fieldStructures parameter like this...
interface FormValues <T extends FieldStructure[]> {
//keys are the names of each field structure
//values are FieldValue<field structure type>
}
interface FormModalProps <T extends FieldStructure[]> {
fieldStructures: T;
handleSubmit: (values: FormValues<T>) => void | Promise<void>;
}
This example feels like an over-simplification, but does anyone know of a way to achieve the same result?
the full code is available on my github at: https://github.com/baldwin-design-co/bdc-components/blob/master/src/form%20modal/form-modal.tsx