Infer from the Type Arguments of a Class
The solution here is interesting, so we'll take it step by step.
We know that cloneComponent
probably needs to be a generic function because we when we pass in Component<any>
, the thing that gets returned is also Component<any>
. It follows then that the result
of calling cloneComponent
is
Transcript
0:00 The solution here is really interesting. We have a cloneComponent function, and we know that this is probably going to be a generic function because when we pass in our components here, we can pass in Component<any>, but that means that the thing that gets returned is a Component<any>, meaning that the results here is typed as any.
0:20 We need to know that the thing that's generic here is the props that are inside that Component. That's the thing that's dynamic about this situation. Knowing that, we know that we probably need a generic slot of some kind, so TProps here.
0:37 What we can do, we know that T component then it's like, we could manually assign this now if we wanted to. We could say, a: number, b: number, and c: number.
0:47 That means that what you end up with is probably going to be if we had a return type here, Component<TProps>. This makes everything pass here. Except, wouldn't it be great if we can just say, the component that you pass in, I want to infer the props that that component has.
1:06 Well, you can. You can say, TProps inside there. Let's keep that return type for now. We can remove this type argument that we're passing and it will now infer that from the thing that's being passed in. If we add a d, which is a number or blah, blah, blah, then you look in the cloneComponent, then it's extracting that as well, and result also has a d on it too.
1:34 This also means that we can remove this cleverly enough because it understands that getProps is returning TProps. The component that's being created is going to be a Component<TProps>, and so the function returns Component<TProps>. Isn't TypeScript clever?
1:50 The cool thing and the thing I want you to take away from this solution is that we're able to put this generic slot inside the type argument of a class or a type helper. This is really cool. We could add this to a promise or something and extract out the results of the promise. It shows you just how flexible these slots really are.