Inference Inception in an Identity Function
Since this one was tricky, let's work through it together.
The first thing we need to do is add a generic called <TObj>
:
export function makeEventHandlers<TObj>(obj: TObj) { return obj;}
Now when we call makeEventHandlers
with our example obj
we're going to see the `nam
Transcript
0:00 Ready? makeEventHandlers. What we can do here is we need a generic. Let's call it TObj, for instance. This TObj, let's imagine that we just pass it in like this. What we're going to get here is we're going to get click name any void, focus name any void.
0:19 You might think it's impossible. Actually, I've come up against this myself. I thought that inferring something from the thing that you're inferring while also using that inference to infect and change the thing that you're trying to infer was impossible, but it's not, using a reversed map type.
0:40 What you can do is instead of saying, "TObj" here, you can say, "K in keyof TObj" is a function that returns void. This function is going to have an argument. Let's just say that argument is string, for now.
0:59 This looks super-weird. Where are you actually inferring the shape of TObj from? It turns out that if you pass in a mapped type like this into the inference slots, then what you're going to get is it's going to infer, basically, an object where the properties are unknown. You're going to get a thing unknown into these inference slots. In other words, it picks up on the keys but not the value.
1:31 What we're going to do is we take TObj. Now we have access to the key via K. arg K, look at that. Oh my God. It's just so cool, it actually then goes back into the object that it's typing. arg click now belongs here, so name is click. You can add something, anythingYouWant, to this. anythingYouWant. You get name. name is going to be anythingYouWant.
2:06 I think this is just so amazing. It gives you a lot of flexibility. This is only possible with a reversed map type and with an identity function. It's so cool.