The type of the source record
The type the guard narrows values to
A new record holding only the accepted entries
const scores = { alice: 1, bob: 2 } as const;
const passing = Obj.filter(scores, (value) => value > 1);
assert.deepStrictEqual(passing, { bob: 2 });
// The key is available as the second argument.
const notAlice = Obj.filter(scores, (_value, key) => key !== 'alice');
assert.deepStrictEqual(notAlice, { bob: 2 });
// A type guard narrows the value type of the result.
const mixed: UnknownRecord = { a: 1, b: 'x' } as const;
const strings = Obj.filter(mixed, isString);
assert.deepStrictEqual(strings, { b: 'x' });
Keeps the entries whose value the predicate accepts, leaving the values themselves untouched.
Type Behavior: the surviving keys are the keys of the source record, made optional — the predicate may reject any of them. A record keyed by an index signature stays total instead, because it names no specific key that could go missing.
Passing a type guard narrows the value type of the result, which is what
Object.fromEntries(Object.entries(record).filter(guard)) loses.
Key handling: keys reach the callback the way Object.entries yields
them, so a numeric key 1 arrives as '1'. Symbol-keyed properties are
not enumerated by Object.entries; they are dropped from both the result
and its type.
The type of the source record
A new record holding only the accepted entries
const scores = { alice: 1, bob: 2 } as const;
const passing = Obj.filter(scores, (value) => value > 1);
assert.deepStrictEqual(passing, { bob: 2 });
// The key is available as the second argument.
const notAlice = Obj.filter(scores, (_value, key) => key !== 'alice');
assert.deepStrictEqual(notAlice, { bob: 2 });
// A type guard narrows the value type of the result.
const mixed: UnknownRecord = { a: 1, b: 'x' } as const;
const strings = Obj.filter(mixed, isString);
assert.deepStrictEqual(strings, { b: 'x' });
Keeps the entries whose value the predicate accepts, leaving the values themselves untouched.
Type Behavior: the surviving keys are the keys of the source record, made optional — the predicate may reject any of them. A record keyed by an index signature stays total instead, because it names no specific key that could go missing.
Passing a type guard narrows the value type of the result, which is what
Object.fromEntries(Object.entries(record).filter(guard))loses.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.