The type of the source record
The type the callback returns for every key
A new record with the same keys as record and the mapped values
const scores = { alice: 1, bob: 2 } as const;
const doubled = Obj.map(scores, (value) => value * 2);
assert.deepStrictEqual(doubled, { alice: 2, bob: 4 });
// The key is available as the second argument.
const labelled = Obj.map(scores, (value, key) => `${key}=${value}`);
assert.deepStrictEqual(labelled, { alice: 'alice=1', bob: 'bob=2' });
Transforms every value of a record, leaving the key set untouched.
Type Behavior: the result is a mapped type over
keyof R, so the keys — and their optional modifiers — survive verbatim:{ a: number; b?: number }maps to{ a: V2; b?: V2 }, and a record with an index signature stays total rather than becomingPartial.This is what
Object.fromEntries(Object.entries(record).map(...))cannot express: an entries array carries no evidence that it still covers every key of the record it came from, so its element type is all the return type can be built from. Going through a mapped type instead states the invariant that a value-only transform preserves the key set.Key handling: keys reach the callback the way
Object.entriesyields them, so a numeric key1arrives as'1'. Symbol-keyed properties are not enumerated byObject.entries; they are dropped from both the result and its type.