Target
Take care about substituting of isInvalid: false and validationPending: false by helper class/function:
const controlsAccess: {
senderName: ControlAccess<string>;
senderPhoneNumber: ControlAccess<number>;
senderAddress: ControlAccess<Address>
} = {
senderName: {
validatablePayload: {
value: "",
isInvalid: false,
validationPending: false
},
vueReferenceID: "SENDER_NAME"
},
senderPhoneNumber: {
validatablePayload: {
value: 0,
isInvalid: false,
validationPending: false
},
vueReferenceID: "SENDER_EMAIL"
},
senderAddress: {
validatablePayload: {
value: { city: "", street: "" },
isInvalid: false,
validationPending: false
},
vueReferenceID: "SENDER_ADDRESS"
}
};
Types:
type ValidatableVModel<Value> = {
isInvalid: boolean;
value: Value;
validationPending: boolean;
};
type ControlAccess<ValidatablePayload> = {
validatablePayload: ValidatableVModel<ValidatablePayload>;
vueReferenceID: string;
};
type Address = {
city: string;
street: string;
}
The final syntax will be like:
const controlsAccess: {
senderName: ControlAccess<string>;
senderPhoneNumber: ControlAccess<number>;
senderAddress: ControlAccess<Address>
} = generateControlAccessObject({
senderName: { vueReferenceID: "SENDER_NAME", initialValue: "" },
senderPhoneNumber: { vueReferenceID: "SENDER_NAME", initialValue: 0 },
senderAddress: { vueReferenceID: "SENDER_ADDRESS", initialValue: { city: "", street: "" } }
})
The JavaScript solution is trivial:
function generateControlAccessObject(dynamicData) {
const accumulatingResult = {};
for (const [ key, data ] of Object.entries(dynamicData)) {
accumulatingResult[key] = {
validatablePayload: {
value: data.initialValue,
isInvalid: false,
validationPending: false
},
vueReferenceID: data.vueReferenceID
}
}
return accumulatingResult;
}
console.log(generateControlAccessObject({
senderName: { vueReferenceID: "SENDER_NAME", initialValue: "" },
senderPhoneNumber: { vueReferenceID: "SENDER_NAME", initialValue: 0 },
senderAddress: { vueReferenceID: "SENDER_ADDRESS", initialValue: { city: "", street: "", } },
}))
Now how to explain TypeScript what is the parameter and what will be returned?
Solution on conceptual level
Let TypeScript know the implicit keys and types relationship:
- senderName:
string - senderPhoneNumber:
number - senderAddress:
Address
My efforts
First the type of controlsAccess__updatedAPI and what return generateInputsAccessObject is incompatible. Next, the accumulatingResult is initially empty which does not match with type annotation. Finally, TypeScript currently don't know what inside data.
const controlsAccess__updatedAPI: {
senderName: ControlAccess<string>;
senderPhoneNumber: ControlAccess<number>;
senderAddress: ControlAccess<Address>
} = generateInputsAccessObject({
senderName: { vueReferenceID: "SENDER_NAME", initialValue: "" },
senderPhoneNumber: { vueReferenceID: "SENDER_NAME", initialValue: 0 },
senderAddress: { vueReferenceID: "SENDER_ADDRESS", initialValue: { city: "", street: "", } },
})
type DynamicData<Keys extends string, Values> = Record<Keys, SingleControlDynamicData<Values>>;
type SingleControlDynamicData<Values> = { initialValue: Values; vueReferenceID: string; };
function generateInputsAccessObject<Keys extends string, Values>(
dynamicData: DynamicData<Keys, Values>
): Record<Keys, { initialValue: Values; vueReferenceID: string; }> {
const accumulatingResult: Record<Keys, { initialValue: string; vueReferenceID: string; }> = {};
for (const [ key, data ] of Object.entries(dynamicData)) {
accumulatingResult[key] = {
validatablePayload: {
value: data.initialValue,
isInvalid: false,
validationPending: false
},
vueReferenceID: data.vueReferenceID
};
}
return accumulatingResult;
}
Requirements
- Please no skipped types annotations
- Please no
anyandobject
