Let’s assume I have two objects that I want to map from one to the other.
// type of the object I want to create
type FruitReport = {
bestBerry: number;
worstBerry: number;
apple: number;
}
// types of objects I receive
type FruitNamesByType = {
berries: 'pineapples' | 'tomatoes';
pommes: 'apples'
}
// I am entirely unsure if the following is also correct:
type FruitData = {
[groupName in keyof FruitNamesByType]: {
fruits: {
[fruitName in FruitNamesByType[groupName]: {
value: number
}
}
}
And so, the objects look like this:
// the object I receive
const fruitData:FruitData = {
berries: {
pineapples: { value: 3 },
tomatoes: { value: 4 },
pommes: {
apples: { value: 1 }
}
}
// the object I create
const fruitReport: FruitReport = {
bestBerry: 3,
worstBerry: 4,
apple: 1
}
Now, I want to use a mapping object to let a reducer know how to transform the initial data into the required format. I set on making it as such (but I’m open to suggestions on changing it):
const fruitMapToReport: ProblematicType = {
bestBerry: ['berries', 'pineapples'] as const,
worstBerry: ['berries', 'tomatoes'] as const,
apple: ['pommes', 'apple'] as const
}
Now, I have a problem with properly typing it, as the second array object is dependent on the first one and the reducer needs to know that pineapples
are indeed a key of berries
and they are not a key of pommes
. That’s why the following simple type won’t cut it:
type ProblematicType = {
[key in keyof FruitReport]: [
keyof FruitData,
FruitData[keyof FruitData],
];
};
As I’m not well-versed in more arcane ways of inferring/asserting types or using generics in mapped types, I have a very hard time coming up with a solution that wouldn’t rely on just hard-casting things with as
. What would be an elegant solution to this?