API reference › @evolu/common › Object › createMutableRecord
Call Signature
function createMutableRecord<K, V>(): Record<K, V>;
Defined in: packages/common/src/Object.ts:344
Creates a mutable Record.
Use it to build a Record locally through mutation, avoiding repeated object spreads. Keep mutation scoped to the constructing function, and treat the completed Record as immutable after it leaves that scope. When a source is provided, its own enumerable properties are shallow-copied. Inherited and non-enumerable properties are not copied.
The Record is created with Object.create(null), so any string can be used
as a key while it is being built. Missing keys such as toString and
constructor do not resolve to inherited values, and assigning __proto__
creates an own data property instead of changing the prototype.
The null prototype makes dynamic construction safer, but it does not have to be preserved. Spreading the completed Record into an ordinary object is supported. Use getOwnProp when a lookup must read only own properties.
For immutable empty application data, defaults, or placeholders, use emptyRecord.
Example
import { assertEqual, createMutableRecord } from "@evolu/common";
const createValuesByKey = (
entries: ReadonlyArray<readonly [string, number]>,
): Readonly<Record<string, number>> => {
const valuesByKey = createMutableRecord<string, number>();
for (const [key, value] of entries) {
valuesByKey[key] = value;
}
return valuesByKey;
};
assertEqual(
createValuesByKey([
["a", 1],
["b", 2],
]),
{ a: 1, b: 2 },
);
Note that TypeScript does not model an object's runtime prototype. A plain
TypeScript Record exposes Object.prototype members even when the runtime
object has a null prototype:
import { assertErr, assertTrue, trySync } from "@evolu/common";
const values = Object.create(null) as Record<string, number>;
// TypeScript accepts the call, but `toString` is undefined at runtime.
// oxlint-disable-next-line typescript/no-base-to-string -- Intentionally calls a method missing from the null-prototype value.
const result = trySync(() => values.toString());
assertErr(result);
assertTrue(result.error instanceof TypeError);
createMutableRecord uses the same TypeScript Record representation.
import {
assertErr,
assertTrue,
createMutableRecord,
trySync,
} from "@evolu/common";
const values = createMutableRecord<string, number>();
// TypeScript accepts the call, but `toString` is undefined at runtime.
// oxlint-disable-next-line typescript/no-base-to-string -- Intentionally calls a method missing from the null-prototype value.
const result = trySync(() => values.toString());
assertErr(result);
assertTrue(result.error instanceof TypeError);
In other words, treat the returned object as string-keyed data rather than calling inherited object methods through it.
Call Signature
function createMutableRecord<T>(source: T): {
-readonly [K in string | number | symbol]: T[K];
};
Defined in: packages/common/src/Object.ts:350
Creates a mutable null-prototype copy of an object.