I'm struggling with a React + TypeScript "problem": it actually don't stop my app, but now I've this doubt I want to remove!.. It's more of a question!
What I would like to achieve is to define the properties name of an object, whereas the properties name are given by variables. Let me explain with an example -> https://codepen.io/Gesma94/pen/xmwMzY
/* The 'data' property is "dynamic": it will always have this structure,
* but the name properties (and the values) may change.
* The 'mapping' property is used to know the name properties inside 'data'.
*/
const series = {
data: [
{map1: "People reached", map2: 200},
{map1: "People who called", map2: 117},
{map1: "Contract signed", map2: 77}
],
mapping: {
stage: "map1",
values: "map2"
}
};
/* This is the actual app. */
const myPar = document.getElementById("myPar");
const { stage: stageLabel, values: valuesLabel} = series.mapping;
series.data.forEach((sample: any, index: number) => {
myPar.innerHTML = myPar.innerHTML + "<br>" + sample[stageLabel];
});
As you can see, in the forEach I write sample: any.
Now, I know sample has a string (the first one will always be a string) property which name is map1, and that's because I retrieved and saved in stageLabel. I also know that the other property is a number (it's always a number) and its name map2 is saved in valueLabel.
Now, what I'm starving to understand is how to not write sample: any, but define the type of sample using the information I retrieved earlier.
Basically, I would like to write something like: sample: {stageLabel: string, valueLabel: number}, but doing this way TypeScript believe sample has the properties stageLabel and valueLabel, since we are in "compile time" and it can't even evaluate the variables.
So, since TypeScript can't know what's inside the variables, I know I can't actually obtain sample: {map1: string, map2: number}, but maybe I can obtain some sort of aliasing.
For example, I write sample: {stageLabel: string, valueLabel: number}, and in the rest of the code I use the properties sample.stageLabel and sample.valueLabel. Then, when the application is running, those property name are evaluated, so sample.stageLabel is actually sample.map1.
I hope I've been clear enough to understand my question.