Announcing: A Free Book, A New Course, A Huge Price Cut...
It's a massive ship day. We're launching a free TypeScript book, new course, giveaway, price cut, and sale.
JSX.IntrinsicElements
is a type in TypeScript's global scope that defines which native JSX elements are in scope, and what props they require.
declare global {
namespace JSX {
interface IntrinsicElements {
"my-custom-element": {
id : string;
};
}
}
}
<my-custom-element />;Property 'id' is missing in type '{}' but required in type '{ id: string; }'.2741Property 'id' is missing in type '{}' but required in type '{ id: string; }'.
In the example above, we:
declare global
.JSX
namespace.IntrinsicElements
interface.The property that we define on the IntrinsicElements
interface is the name of the element we want to define. The value of the property is the props that the element accepts.
This works because interfaces in the same scope merge their declarations. This means that the IntrinsicElements
interface we define will merge with the one that TypeScript already knows about.
If you try to use an element that isn't defined on JSX.IntrinsicElements
, you'll get an error:
Property 'X' does not exist on type 'JSX.IntrinsicElements'.
const Component = () => {
return < i-am-not-defined /> ;Property 'i-am-not-defined' does not exist on type 'JSX.IntrinsicElements'.2339Property 'i-am-not-defined' does not exist on type 'JSX.IntrinsicElements'.};
Mostly, you won't modify JSX.InstrinsicElements
yourself. Instead, the framework you're using will define the elements for you.
For instance, React uses JSX.IntrinsicElements
to define the props for native HTML elements.
Pressing cmd-click
on a JSX element in VSCode will take you to the definition of the element - and the definition is pretty enormous:
declare global {
namespace JSX {
interface IntrinsicElements {
a: React.DetailedHTMLProps<
React.AnchorHTMLAttributes<HTMLAnchorElement>,
HTMLAnchorElement
>;
abbr: React.DetailedHTMLProps<
React.HTMLAttributes<HTMLElement>,
HTMLElement
>;
address: React.DetailedHTMLProps<
React.HTMLAttributes<HTMLElement>,
HTMLElement
>;
// ... hundreds more
}
}
}
Fundamentally, this is doing exactly the same thing as our code above. The name of the property is the name of the element, and the value is the props that the element accepts.
React.DetailedHTMLProps
is just a utility type that creates the types that a
, abbr
, and address
accept.
Share this article with your friends
It's a massive ship day. We're launching a free TypeScript book, new course, giveaway, price cut, and sale.
Learn why the order you specify object properties in TypeScript matters and how it can affect type inference in your functions.
Learn how to use corepack
to configure package managers in Node.js projects, ensuring you always use the correct one.
Learn how to strongly type process.env in TypeScript by either augmenting global type or validating it at runtime with t3-env.
Discover when it's appropriate to use TypeScript's any
type despite its risks. Learn about legitimate cases where any
is necessary.
Learn why TypeScript's types don't exist at runtime. Discover how TypeScript compiles down to JavaScript and how it differs from other strongly-typed languages.