Repository: apache/superset
File: superset-frontend/src/features/databases/DatabaseModal/ExtraOptions.tsx (TypeScript)

Code before:
  StyledInputContainer,
  StyledJsonEditor,
  StyledExpandableForm,
  no_margin_bottom,
} from './styles';
import { DatabaseObject, ExtraJson } from '../types';

const ExtraOptions = ({
  db,
  onInputChange,
  onTextChange,
  onEditorChange,
  onExtraInputChange,
  onExtraEditorChange,
  extraExtension,
}: {
  db: DatabaseObject | null;
  onInputChange: (
    e: CheckboxChangeEvent | React.ChangeEvent<HTMLInputElement>,
  ) => void;
  onTextChange: EventHandler<ChangeEvent<HTMLTextAreaElement>>;
  onEditorChange: Function;
  onExtraInputChange: (
    e:
      | CheckboxChangeEvent
      | React.ChangeEvent<HTMLInputElement>
      | {
          target: {
            type: string;
            name: string;
            value: string;
            checked?: boolean;
          };
        },
  ) => void;
  onExtraEditorChange: Function;
  extraExtension: DatabaseConnectionExtension | undefined;
}) => {
  const expandableModalIsOpen = !!db?.expose_in_sqllab;
  const createAsOpen = !!(db?.allow_ctas || db?.allow_cvas);
  const isFileUploadSupportedByEngine =
    db?.engine_information?.supports_file_upload;
  const supportsDynamicCatalog =
    db?.engine_information?.supports_dynamic_catalog;

  // JSON.parse will deep parse engine_params
  // if it's an object, and we want to keep it a string
  const extraJson: ExtraJson = JSON.parse(db?.extra || '{}', (key, value) => {
    if (key === 'engine_params' && typeof value === 'object') {
      // keep this as a string
      return JSON.stringify(value);

Review comment (suggestion):
```suggestion
      | ChangeEvent<HTMLInputElement>
```

Code after:
  StyledInputContainer,
  StyledJsonEditor,
  StyledExpandableForm,
  no_margin_bottom,
} from './styles';
import { DatabaseObject, ExtraJson } from '../types';

const ExtraOptions = ({
  db,
  onInputChange,
  onTextChange,
  onEditorChange,
  onExtraInputChange,
  onExtraEditorChange,
  extraExtension,
}: {
  db: DatabaseObject | null;
  onInputChange: (
    e: CheckboxChangeEvent | React.ChangeEvent<HTMLInputElement>,
  ) => void;
  onTextChange: EventHandler<ChangeEvent<HTMLTextAreaElement>>;
  onEditorChange: Function;
  onExtraInputChange: (
    e: CheckboxChangeEvent | ChangeEvent<HTMLInputElement>,
  ) => void;
  onExtraEditorChange: Function;
  extraExtension: DatabaseConnectionExtension | undefined;
}) => {
  const expandableModalIsOpen = !!db?.expose_in_sqllab;
  const createAsOpen = !!(db?.allow_ctas || db?.allow_cvas);
  const isFileUploadSupportedByEngine =
    db?.engine_information?.supports_file_upload;
  const supportsDynamicCatalog =
    db?.engine_information?.supports_dynamic_catalog;

  // JSON.parse will deep parse engine_params
  // if it's an object, and we want to keep it a string
  const extraJson: ExtraJson = JSON.parse(db?.extra || '{}', (key, value) => {
    if (key === 'engine_params' && typeof value === 'object') {
      // keep this as a string
      return JSON.stringify(value);
    }
    return value;
  });

  // JSON validation hooks for the three editors
  const secureExtraAnnotations = useJsonValidation(db?.masked_encrypted_extra, {
    errorPrefix: 'Invalid secure extra JSON',
  });

  const metadataParamsValue = !Object.keys(extraJson?.metadata_params || {})