Generics are really interesting in that they're tied to a function's execution context. What that means is that you can make a function, which has one generic locked inside of it, then make another function, in the future, out of that function, with the first generic still locked, and then add another one.
Here's what I mean by that. We want to make a function called makeKeyRemover. Now, makeKeyRemover, is going to return a function that removes keys from an object.
export const makeKeyRemover = () => () => {};
const keyRemover = makeKeyRemover(["a", "b"]);
const newObject = keyRemover({a: 1, b: 2, c: 3});
The expected case for newObject is that it's going to be an object with just the key of c. In keyRemover, we're making a function. In newObject, we're actually calling the function and using it.
To make this work, first of all, what we're going to do is say, <Key extends string> in makeKeyRemover.
export const makeKeyRemover = <Key extends string>() => () => {};
And then we're going to say that the argument keys is an array of keys. The key's generic has been locked in as a or b.
export const makeKeyRemover = <Key extends string>(keys: Key[]) => () => {};
What we want to do next is take in the object, which is going to be the generic Obj. Then, I'll set the argument obj to Obj.
export const makeKeyRemover =
<Key extends string>(keys: Key[]) =>
<Obj>(obj: Obj) => {};
The generic is now locked in the keyRemover. That means that we need to just remove the keys from the object.
To do that we'll set the return type of this function to be Omit<Obj, Key>. Then we'll return that blank object and set the type to any to quite down an error.
export const makeKeyRemover =
<Key extends string>(keys: Key[]) =>
<Obj>(obj: Obj): Omit<Obj, Key> => {
return {} as any;
};
What's going on here is that now we've got Omit, which removes keys from an object.
We're removing a and b, the keyRemover locks in that first generic, Key. Then newObject, when we instantiate the second function, locks in the generic, Obj. Now, newObject only has c available to it.
Pretty cool!
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.