These TypeScript objects have identical keys but different properties. My goal is to merge the properties from one object onto the other.
interface Stat<T, V> {
name: string;
description: string;
formatValue: (params: { value: V; item: T }) => string;
}
type Currency = 'USD' | 'CAD';
interface Item {
id: number;
product: string;
earnings: number;
currency: Currency;
// etc.
}
type Stats<T> = { [P in keyof T]: Stat<T, T[P]> };
// Interested in combining the first object...
const items: Stats<Item> = {
id: {
name: 'ID',
description: 'Unique identifier for a sales item.',
formatValue: ({ value }) => String(value),
},
product: {
name: 'Product',
description: 'The name of the product sold.',
formatValue: ({ value }) => value,
},
earnings: {
name: 'Earnings',
description: 'The dollar value earned in the appropriate currency.',
formatValue: ({ value, item }) => Intl.NumberFormat('en-us', { style: 'currency', currency: item.currency }).format(value),
},
currency: {
name: 'Currency',
description: 'The currency used during the sale.',
formatValue: ({ value }) => value,
},
};
interface Column {
width: number;
align?: string;
}
type Columns<T> = { [P in keyof T]: Column };
// Interested in combining the second object...
const columns: Columns<Item> = {
id: { width: 50, align: 'right' },
product: { width: 200 },
earnings: { width: 100, align: 'right' },
currency: { width: 75 },
};
My intention is to extract the formatValue
function from items
and incorporate it into columns
under the appropriate key. I am facing complexity due to the differing typing around formatValue
for each key while trying to preserve the types.
const result = {
id: {
width: 50,
align: 'right',
formatValue: ({ value }) => String(value),
},
product: {
width: 200,
formatValue: ({ value }) => value,
},
earnings: {
width: 100,
align: 'right',
formatValue: ({ value, item }) => Intl.NumberFormat('en-us', { style: 'currency', currency: item.currency }).format(value),
},
currency: {
width: 75,
formatValue: ({ value }) => value,
},
};
Edit: To provide more clarity, I tried using a typed version of Object.fromEntries
to loop through each key in the items
/columns
variables. However, this led to the issue of each property's value (especially around formatValue
) becoming a union of all possible types, rather than maintaining the intended underlying types.
Here's an updated playground demonstrating what I'm trying to achieve. Note the incorrect typing on the resulting formatValue
function.