Types Deep Dive 10 exercises

Extend JSX.IntrinsicElements with Declaration Merging

For the solution to this challenge, we'll name the element <something-solution>.

From the error message, we know that the something-solution element does not exist on the type JSX.IntrinsicElements.

This tells us that we need to use declaration merging to extend the JSX.IntrinsicElements

Loading solution


00:00 So the thing we know from this error is that JSX.IntrinsicElements is the thing we want to target with our declaration merge. We want to pull this into the global scope here, so we'll declare global. To declare global, we're going to basically say,

00:16 we need to go onto the namespace JSX and inside there, we're going to go interface intrinsic elements. I have to make sure to spell this right, intrinsic elements, and then say something solution, because it has to be inside a string here, otherwise it's invalid,

00:33 and we're going to say ID string. Now here, it starts to work and we actually get, you can see here, there we go, JSX.IntrinsicElements something solution ID string. If we command click, we actually go to this definition up here, whereas if we were to command click on a div, let's say, we would actually go all the way

00:51 into JSX.IntrinsicElements here. You're starting to see how declaration merging can be pretty powerful here, because we can actually describe custom stuff that we can render, which is really, really interesting. So now, if we pass in like the wrong thing, if we don't pass in an ID, it's missing in type empty object, but required in this,

01:09 and also if we pass it as the wrong thing, this is going to yell at us because it's expecting a string. Very, very cool. And you notice as well, that JSX.IntrinsicElements, it's also available inside the namespace React, JSX.IntrinsicElements. So up here, for instance, this also will work.

01:29 This is interesting because JSX.IntrinsicElements, it's available on the JSX namespace, but that's global. And if for whatever reason, you have types that are coming in from, let's say, React, but also another framework that uses JSX, like SolidJS or Preact, for instance, you actually want to say,

01:48 okay, this is only available inside React's namespace of JSX. So it gets a little bit confusing here, but really the main thing is that both of these will work. And probably you want to be more specific, I would say. So you probably want to say React.JSX.IntrinsicElements. But then again, how often are you going to be combining

02:06 two frameworks in the same project? So I would usually just say, namespace JSX.IntrinsicElements, add your extra kind of elements on there and type the props. Not bad.