I have a STEPS_CONFIG
object that defines various steps, each with a set of properties including defaultValues
. However, when I try to access defaultValues
from the currentStep
object, TypeScript throws an error indicating that the property does not exist on the type.
Here’s a version of the relevant code:
export const STEPS = {
init: 'init',
profile_picture: 'profile_picture',
driving_license_front: 'driving_license_front',
driving_license_back: 'driving_license_back',
vehicle_card_front: 'vehicle_card_front',
vehicle_card_back: 'vehicle_card_back',
vehicle_insurance: 'vehicle_insurance',
verification_photo: 'verification_photo',
applicant_contract: 'applicant_contract',
} as const;
export const STEPS_CONFIG = () => ({
[STEPS.init]: {
title: `${t('enterBasicInformation')}`,
renderForm: <Init />,
// TODO: Remove unused properties from the init step and fix possible errors
properties: {
boxTitle: 'Box Title',
rulesList: ['rule1', 'rule2', 'rule3'],
image: 'aedfsdafsdf',
selfieMode: false,
enabled: false,
},
onSubmit: async (data: any) => {
const formattedData = {
vehicle_type: 'cab' as const,
referral_code: toEnNumbers(data.referralCode),
national_code: toEnNumbers(data.nationalCode)!,
activity_location: data.activityLocation.id as number,
father_name: data.fatherName as string,
};
const response = await init(formattedData);
if (response.ok) {
useWizardStore
.getState()
.addRemainingSteps(response.body.remaining_steps);
}
return response;
},
defaultValues: {
vehicleType: 'سواری',
haveReferralCode: false,
activityLocation: null,
fatherName: '',
nationalCode: '',
},
},
[STEPS.profile_picture]: {
title: `${t('uploadProfilePicture')}`,
description: `${t('takeSelfieRule')}`,
properties: {
boxTitle: `${t('userSelfie')}`,
rulesList: [
`${t('fullViewImageRule')}`,
`${t('profilePictureExtraRules')}`,
],
image: getFileURL('images/rules/profile-picture.svg'),
correctionImage: useWizardStore.getState().remainingSteps.profile_picture,
selfieMode: true,
enabled: true,
},
onSubmit: async (data: any) => {
const formattedData = {
kind: STEPS.profile_picture,
image: data.image,
};
const response = await uploadDocument(formattedData);
return response;
},
},
[STEPS.driving_license_front]: {
title: `${t('uploadDrivingLicenseFront')}`,
description: `${t('takeDrivingLicnseRuleFront')}`,
renderForm: <DrivingLicenseFront />,
properties: {
boxTitle: `${t('drivingLicenseFrontImage')}`,
rulesList: [`${t('originalDocumentRules')}`, `${t('overEighteenRules')}`],
image: getFileURL('images/rules/driving-license-front.svg'),
correctionImage:
useWizardStore.getState().remainingSteps.driving_license_front,
selfieMode: false,
enabled: true,
},
onSubmit: async (data: any) => {
const formattedData = {
kind: STEPS.driving_license_front,
image: data.image,
first_name: data.firstName,
last_name: data.lastName,
birth_date: toEnNumbers(data.birthDate)!,
gender: data.gender.value,
license_issuance_date: toEnNumbers(data.licenseIssuanceDate)!,
license_valid_for: data.drivingLicenseValidityPeriod.value,
license_type: data.drivingLicenseType.value,
license_number: toEnNumbers(data.drivinglicenseNumber)!,
};
const response = await uploadDocument(formattedData);
return response;
},
},
[STEPS.driving_license_back]: {
title: `${t('uploadDrivingLicenseBack')}`,
description: `${t('takeDrivingLicnseRuleBack')}`,
properties: {
boxTitle: `${t('drivingLicenseBackImage')}`,
rulesList: [
`${t('originalDocumentRules')}`,
`${t('readableDrivingLicenseBack')}`,
],
image: getFileURL('images/rules/driving-license-back.svg'),
correctionImage:
useWizardStore.getState().remainingSteps.driving_license_back,
selfieMode: false,
enabled: true,
},
onSubmit: async (data: any) => {
const formattedData = {
kind: STEPS.driving_license_back,
image: data.image,
};
const response = await uploadDocument(formattedData);
return response;
},
},
[STEPS.vehicle_card_front]: {
title: `${t('uploadVehicleCardFront')}`,
description: `${t('takeVehicleCardFrontRule')}`,
renderForm: <VehicleCardFront />,
properties: {
boxTitle: `${t('vehicleCardFrontImage')}`,
rulesList: [
`${t('originalDocumentRules')}`,
`${t('clearDocumentRules')}`,
`${t('exactCarRules')}`,
],
image: getFileURL('images/rules/vehicle-card-front.svg'),
correctionImage:
useWizardStore.getState().remainingSteps.vehicle_card_front,
selfieMode: false,
enabled: true,
},
onSubmit: async (data: any) => {
const formattedData = {
kind: STEPS.vehicle_card_front,
image: data.image,
...(data.plate.part_a && { plate_part_a: data.plate.part_a }),
...(data.plate.part_b && { plate_part_b: data.plate.part_b }),
...(data.plate.iran_id && { plate_iran_id: data.plate.iran_id }),
...(data.plate.character && { plate_character: data.plate.character }),
plate_type: data.plate.type,
vin: data.vin,
};
const response = await uploadDocument(formattedData);
return response;
},
defaultValues: {
plate: {
type: 1,
part_a: null,
part_b: null,
character: null,
iran_id: null,
},
vin: '',
},
},
[STEPS.vehicle_card_back]: {
title: `${t('uploadVehicleCardBack')}`,
description: `${t('takeVehicleCardBackRule')}`,
renderForm: <VehicleCardBack />,
properties: {
boxTitle: `${t('vehicleCardBackImage')}`,
rulesList: [
`${t('originalDocumentRules')}`,
`${t('clearDocumentRules')}`,
`${t('exactCarRules')}`,
],
image: getFileURL('images/rules/vehicle-card-back.svg'),
correctionImage:
useWizardStore.getState().remainingSteps.vehicle_card_back,
selfieMode: false,
enabled: true,
},
onSubmit: async (data: any) => {
const formattedData = {
kind: STEPS.vehicle_card_back,
image: data.image,
vehicle_model_id: data.vehicleModel.id,
vehicle_color_id: data.vehicleColor.id,
fuel_type: data.fuelType.value,
vehicle_production_year: toEnNumbers(data.productionYear)!,
};
const response = await uploadDocument(formattedData);
return response;
},
defaultValues: {
vehicleColor: null,
vehicleModel: null,
productionYear: '',
},
},
[STEPS.vehicle_insurance]: {
title: `${t('uploadVehicleInsurance')}`,
description: `${t('takeVehicleInsuranceRule')}`,
renderForm: <VehicleInsurance />,
properties: {
boxTitle: `${t('vehicleInsuranceImage')}`,
rulesList: [
`${t('originalDocumentRules')}`,
`${t('fillInsuranceCodeRules')}`,
`${t('insuranceCodeDigitsRules')}`,
`${t('onlyInsuranceCodeRules')}`,
`${t('theNewestVehicleInsuranceRules')}`,
],
image: getFileURL('images/rules/vehicle-insurance.svg'),
correctionImage:
useWizardStore.getState().remainingSteps.vehicle_insurance,
selfieMode: false,
enabled: true,
},
onSubmit: async (data: any) => {
const formattedData = {
kind: STEPS.vehicle_insurance,
image: data.image,
insurance_id: toEnNumbers(data.insuranceNumber)!,
insurer_national_code: toEnNumbers(data.insurerNationalCode)!,
insurance_expiration_date: toEnNumbers(data.insuranceExpirationDate)!,
};
const response = await uploadDocument(formattedData);
return response;
},
defaultValues: {
hasInsuranceNumber: false,
},
},
[STEPS.verification_photo]: {
title: `${t('verificationPhoto')}`,
description: `${t('takeVerificationPhotoRule')}`,
properties: {
boxTitle: `${t('verificationImage')}`,
rulesList: [`${t('keepLicenseRules')}`],
image: getFileURL('images/rules/verification-photo.svg'),
correctionImage:
useWizardStore.getState().remainingSteps.verification_photo,
selfieMode: true,
enabled: true,
},
onSubmit: async (data: any) => {
const formattedData = {
kind: STEPS.verification_photo,
image: data.image,
};
const response = await uploadDocument(formattedData);
return response;
},
},
[STEPS.applicant_contract]: {
title: `${t('takeSignatureTitle')}`,
renderForm: <ApplicantContract />,
properties: {
boxTitle: `${t('takeSignatureTitle')}`,
rulesList: [
`${t('uploadContractRules')}`,
`${t('confirmContractRules')}`,
],
image: getFileURL('images/rules/applicant-signature.svg'),
correctionImage:
useWizardStore.getState().remainingSteps.applicant_contract,
selfieMode: false,
enabled: true,
},
onSubmit: async (data: any) => {
const formattedData = {
kind: STEPS.applicant_contract,
image: data.image,
training_place_id: data.trainingPlace.id,
};
const response = await uploadDocument(formattedData);
return response;
},
},
});
const currentStep =
STEPS_CONFIG()[stepLabels[activeStep] as keyof typeof STEPS];
const methods = useForm({
mode: 'all',
defaultValues: currentStep.defaultValues,
});
and in this line
defaultValues: currentStep.defaultValues,
I got this error
Property 'defaultValues' does not exist on type '{ title: string; description: string; properties: { boxTitle: string; rulesList: string[]; image: string; correctionImage: { image_url: string; message: string; } | undefined; selfieMode: boolean; enabled: boolean; }; onSubmit: (data: any) => Promise<any>; }'.
2
Answers
Maybe you can try:
Define an interface for the structure of each step in STEPS_CONFIG. Ensure this interface includes the defaultValues property.
Than something like this:
You do not have a
defaultValues
property on every possible value, thus Typescript (correctly) does not infer it in the resulting type. I would advise against using such a huge type structure without an explicit type or interface definition.Define an interface for the STEPS_CONFIG values explicitly.
That also has the advantage that you have type validation for your step definitions.