I want to replicate lodash\'s _.omit
function in plain typescript. omit
should return an object with certain properties removed specified via parameter
interface Omit {
(obj: T, ...keys: K): {
[K2 in Exclude]: T[K2]
}
}
const omit: Omit = (obj, ...keys) => {
const ret = {} as {
[K in keyof typeof obj]: (typeof obj)[K]
};
let key: keyof typeof obj;
for (key in obj) {
if (!(keys.includes(key))) {
ret[key] = obj[key];
}
}
return ret;
};
For convenience I've pulled most of the typings to an interface.
The problem was that K
had been being inferred as a tuple, not as a union of keys. Hence, I changed it's type constraint accordingly:
[...(keyof T)[]] // which can be broke down to:
keyof T // a union of keys of T
(keyof T)[] // an array containing keys of T
[...X] // a tuple that contains X (zero or more arrays like the described one above)
Then, we need to transform the tuple K
to a union (in order to Exclude
it from keyof T
). It is done with K[number]
, which is I guess is self-explaining, it's the same as T[keyof T]
creating a union of values of T
.
Playground