Coding problem · Easy · Language Idioms
Typed pick() and omit()
Easy Language practicals Seen at Microsoft, Atlassian
Implement two helpers that are common in API layers (e.g. stripping password from a user before returning it):
function pick<T extends object, K extends keyof T>(obj: T, keys: readonly K[]): Pick<T, K>
function omit<T extends object, K extends keyof T>(obj: T, keys: readonly K[]): Omit<T, K>
Neither may mutate obj. pick only includes keys that exist on the object.
Hints
Hint 1
K extends keyof T means only real keys of T can be passed — typos become compile errors.
Hint 2
Copy with { ...obj } and delete for omit, or build a new object from entries.
Write and run your solution
Loading the editor… (JavaScript is required to run code in your browser.)
Solution and explanation
Show the solution
Time O(keys) for pick, O(fields) for omit · Space O(fields)
keyof T constrains the key list at compile time, and the built-in mapped types Pick<T, K> / Omit<T, K> describe the result, so omit(user, ["password"]).password is a type error. At runtime, pick copies own properties only and omit deletes from a shallow copy.
Note that omit is a shallow copy — nested objects are still shared with the original.
Reference solution
function pick<T extends object, K extends keyof T>(obj: T, keys: readonly K[]): Pick<T, K> {
const out = {} as Pick<T, K>;
for (const key of keys) {
if (Object.prototype.hasOwnProperty.call(obj, key)) out[key] = obj[key];
}
return out;
}
function omit<T extends object, K extends keyof T>(obj: T, keys: readonly K[]): Omit<T, K> {
const copy = { ...obj };
for (const key of keys) delete copy[key];
return copy as Omit<T, K>;
}
Common mistakes
- Mutating the input with
delete obj[key]. - Typing keys as
string[], which loses the connection toT.
Follow-up questions
- Write a
DeepReadonly<T>type. - Use
satisfiesto validate config objects without widening.