const chains = {
ethereum: { namespace: 'eip155', reference: '1' },
solana: { namespace: 'solana', reference: 'mainnet' },
} as const;
const withChainId = objectExtendEach(chains, v => ({
chainId: `${v.namespace}:${v.reference}`,
}));
// {
// ethereum: { namespace: 'eip155'; reference: '1' } & { chainId: string };
// solana: { namespace: 'solana'; reference: 'mainnet' } & { chainId: string };
// }
Each value in original must be an object, because the implementation
spreads v ({ ...v, ...extendFn(v, k) }) — spreading a primitive
would silently yield an empty object (or, for strings, per-character
indices) and the intersection O[K] & Ex would collapse to never
for primitive O[K]. Constraining O to Record<string, object>
makes the type and runtime behavior agree.
Like objectMap, but preserves the per-key correlation between each original value's type and the result by extending every value with the same additional properties rather than mapping it to an unrelated type. Phrasing the result as
{ [K in keyof O]: O[K] & Ex }in the return type evaluatesO[K]fresh per key, where a single generic R would collapse to a union.