skip to Main Content

I am getting a type error in <RenderFormFields formFields={formFieldsData} /> that:-

Types of property 'type' are incompatible. Type 'string' is not assignable to type '"select"'.ts(2322) RenderFormFields.tsx(17, 3): The expected type comes from property 'formFields' which is declared here on type 'IntrinsicAttributes & RenderFormFieldsProps'

Interestingly, when I remove the conditional insertion part from the array, this type error vanishes !

import RenderFormFields from '@common/RenderFormFields';
import {
  BlockSeparator, PrimaryButton,
  PrimaryInput, PrimarySelect,
} from '@paf-ui-components-library';
import { IProps } from '@paf-ui-components-library/PrimaryInput';
import React from 'react';

import AnnualRevenueField from './AnnualRevenueField';
import BranchLocationsField from './BranchLocationsField';
import CurrentBankStatementsField from './CurrentBankStatementsField';
import useBusinessInformationForm from './hooks/useBusinessForm';
import MajorCustomersField from './MajorCustomersField';
import MajorSuppliersField from './MajorSuppliersField';
import PrimaryBankField from './PrimaryBankField';
import TradeAreasField from './TradeAreasField';

export const RefactoredBusinessInformationForm: React.FC = () => {
  const {
    annualRevenueTypeOptions,
    appendBranchLocations,
    appendMajorCustomers,
    appendMajorSuppliers,
    appendPrimaryTradeAreas,
    branchLocationFields,
    businessIndustryOptions,
    handleContinue,
    handleSubmit,
    industryType,
    loading,
    majorCustomersFields,
    majorSuppliersFields,
    naicsCodeOptions,
    primaryTradeAreaFields,
    removeBranchLocations,
    removeMajorCustomers,
    removeMajorSuppliers,
    removePrimaryTradeAreas,
    watch,
  } = useBusinessInformationForm();

  const formFieldsData = [
    {
      data: businessIndustryOptions,
      name: 'businessInformation.industryType',
      title: 'Business Industry',
      type: 'select',
    },
// when I remove this conditional insertion, the type error vanishes !
    ...(industryType === 'Other' ? [{ 
      name: 'businessInformation.otherIndustryType',
      title: 'Other Business Industry Type',
      type: 'text',
    }] : [{}]),
    {
      data: naicsCodeOptions,
      name: 'businessInformation.naicsCode',
      title: 'NAICS Code',
      type: 'select',
    },
    {
      info: 'Describe the business revenue generating activity',
      name: 'businessInformation.natureOfBusiness',
      title: 'Nature of Business',
      type: 'textarea',
    },
    {
      info: 'Provide a description of your products and/or services',
      name: 'businessInformation.businessProductsAndServices',
      title: 'Business Products and Services',
      type: 'textarea',
    },
    {
      name: 'businessInformation.numberOfBranches',
      title: 'Number of Branches',
      type: 'number',
      allowedDecimalPlaces: 0,
    },
  ];

  return (
    <>
      <BlockSeparator
        heading="Business Information"
      >

        <RenderFormFields formFields={formFieldsData} />
        <h1>bruh</h1>

        <PrimarySelect
          data={businessIndustryOptions}
          name="businessInformation.industryType"
          title="Business Industry"
        />
        {industryType === 'Other' && (
          <PrimaryInput
            name="businessInformation.otherIndustryType"
            title="Other Business Industry Type"
            type="text"
          />
        )}
        <PrimarySelect
          data={naicsCodeOptions}
          name="businessInformation.naicsCode"
          title="NAICS Code"
        />

        <PrimaryInput
          info="Describe the business revenue generating activity"
          name="businessInformation.natureOfBusiness"
          title="Nature of Business"
          type="textarea"
        />

        <PrimaryInput
          info="Provide a description of your products and/or services"
          name="businessInformation.businessProductsAndServices"
          title="Business Products and Services"
          type="textarea"
        />

        <PrimaryInput
          allowedDecimalPlaces={0}
          name="businessInformation.numberOfBranches"
          title="Number of Branches"
          type="number"
        />

        <BranchLocationsField
          branchLocationFields={branchLocationFields}
          onAdd={appendBranchLocations}
          onRemove={removeBranchLocations}
        />

        <PrimaryInput
          name="businessInformation.noOfEmployees"
          title="Number of Employees"
          type="number"
        />

        <TradeAreasField
          onAdd={appendPrimaryTradeAreas}
          onRemove={removePrimaryTradeAreas}
          primaryTradeAreaFields={primaryTradeAreaFields}
        />

        <MajorCustomersField
          majorCustomersFields={majorCustomersFields}
          onAdd={appendMajorCustomers}
          onRemove={removeMajorCustomers}
        />

        <MajorSuppliersField
          majorSuppliersFields={majorSuppliersFields}
          onAdd={appendMajorSuppliers}
          onRemove={removeMajorSuppliers}
        />

        <PrimaryBankField />

        <CurrentBankStatementsField
          existingDocumentUrl={watch('businessInformation.currentBankStatementsDoc.frontSideUrl')}
        />

        <AnnualRevenueField
          annualRevenueTypeOptions={annualRevenueTypeOptions}
        />
      </BlockSeparator>

      <BlockSeparator>
        <PrimaryButton
          loading={loading}
          onClick={handleSubmit(({ businessInformation }) => (
            handleContinue(businessInformation)
          ))}
          variantsStyle={['primary-button-submit-accent']}
        >
          Continue
        </PrimaryButton>
      </BlockSeparator>
    </>
  );
};

RenderFormFields.tsx

import {
  PrimaryInput, PrimarySelect,
} from '@paf-ui-components-library';
import { IProps as PrimaryInputProps } from '@paf-ui-components-library/PrimaryInput';
import { IProps as PrimarySelectProps } from '@paf-ui-components-library/PrimarySelect';
import React from 'react';

export interface PrimaryInputField extends PrimaryInputProps {
  type: 'text' | 'number' | 'textarea';
}
interface PrimarySelectField extends PrimarySelectProps {
  type: 'select';
}
type FormField = PrimaryInputField | PrimarySelectField;

interface RenderFormFieldsProps {
  formFields: FormField[];
}

const RenderFormFields: React.FC<RenderFormFieldsProps> = ({ formFields }) => (
  <>
    {formFields.map((field) => (
      <React.Fragment key={field.name}>
        {field.type === 'select' && (
          <PrimarySelect data={field.data} name={field.name} title={field.title} />
        )}
        {field.type === 'text' && (
          <PrimaryInput name={field.name} title={field.title} type="text" />
        )}
        {field.type === 'textarea' && (
          <PrimaryInput info={field.info} name={field.name} title={field.title} type="textarea" />
        )}
        {field.type === 'number' && (
          <PrimaryInput
            allowedDecimalPlaces={(field as PrimaryInputField).allowedDecimalPlaces}
            name={field.name}
            title={field.title}
            type="number"
          />
        )}
      </React.Fragment>
    ))}
  </>
);

export default RenderFormFields;

2

Answers


  1. Chosen as BEST ANSWER

    I was able to fix this issue by using the as keyword.

    In TypeScript, the as keyword is used to explicitly type cast a value to a different type.

      const formFieldsData: FormField[] = [
        {
          data: businessIndustryOptions,
          name: 'businessInformation.industryType',
          title: 'Business Industry',
          type: 'select',
        },
        ...(industryType
          ? [
            {
              name: 'businessInformation.otherIndustryType',
              title: 'Other Business Industry Type',
              type: 'text',
            } as FormField,
          ]
          : []),
        {
          data: naicsCodeOptions,
          name: 'businessInformation.naicsCode',
          title: 'NAICS Code',
          type: 'select',
        },
        {
          info: 'Describe the business revenue generating activity',
          name: 'businessInformation.natureOfBusiness',
          title: 'Nature of Business',
          type: 'textarea',
        },
        {
          info: 'Provide a description of your products and/or services',
          name: 'businessInformation.businessProductsAndServices',
          title: 'Business Products and Services',
          type: 'textarea',
        },
        {
          name: 'businessInformation.numberOfBranches',
          title: 'Number of Branches',
          type: 'number',
          allowedDecimalPlaces: 0,
        },
      ];
    

  2. The error occurs because you’re conditionally inserting an empty object ([{}]) into formFieldsData when industryType !== 'Other', which doesn’t match the expected FormField type. To fix it, replace the conditional spread with an empty array when the condition is false:

    ...(industryType === 'Other' ? [{ 
      name: 'businessInformation.otherIndustryType',
      title: 'Other Business Industry Type',
      type: 'text',
    }] : []),
    

    This change ensures that only objects matching the FormField type are inserted into formFieldsData, eliminating the type error.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search