Filtering Object Properties in TypeScript
If you use TypeScript, you’ve more than likely seen keyof typeof obj
at
one point or another to get a union type representing the keys of the given
object. But what if we want to get a subset of the object keys, based on
the values in the object?
We can do this by creating a Filter
type which will take two generic
arguments: the object type and the type of values to keep.
type Filter<Obj, ValueType> = {
[K in keyof Obj]: Obj[K] extends ValueType ? K : never
}
A real-world use case for this might be a maxBy
function that we can pass
an array of objects and a key which we want to find the max value of. We
can use Filter<T, number>
to only allow keys which are numeric values
since no other data type makes sense for this use case.
export function maxBy<
T extends Record<string, unknown>,
K extends Filter<T, number>[keyof T],
>(collection: T[], by: K): number {
return collection.reduce(
(acc, item) => Math.max(item[by] as number, acc),
0,
)
}