I want to replicate lodash\'s _.omit function in plain typescript. omit should return an object with certain properties removed specified via parameter
Object.keys or for in returns keys as string and excludes symbols. Numeric keys are also converted to strings.
You need to convert numeric string keys to numbers otherwise it will return the object with string keys.
function omit,
K extends [...(keyof T)[]]>(
obj: T,
...keys: K
): { [P in Exclude]: T[P] } {
return (Object.keys(obj)
.map((key) => convertToNumbers(keys, key)) as Array)
.filter((key) => !keys.includes(key))
.reduce((agg, key) => ({ ...agg, [key]: obj[key] }), {}) as {
[P in Exclude]: T[P];
};
}
function convertToNumbers(
keys: Array,
value: string | number
): number | string {
if (!isNaN(Number(value)) && keys.some((v) => v === Number(value))) {
return Number(value);
}
return value;
}
// without converToNumbers omit({1:1,2:'2'}, 1) will return {'1':1, '2':'2'}
// Specifying a numeric string instead of a number will fail in Typescript
To include symbols you can use the code below.
function omit(
obj: T,
...keys: K
): { [P in Exclude]: T[P] } {
return (Object.getOwnPropertySymbols(obj) as Array)
.concat(Object.keys(obj)
.map((key) => convertToNumbers(keys, key)) as Array)
.filter((key) => !keys.includes(key))
.reduce((agg, key) => ({ ...agg, [key]: obj[key] }), {}) as {
[P in Exclude]: T[P];
};
}