If you're only here for a quick reference to the syntax, here you go:
import React from 'react';
import * as CSS from 'csstype';
// Get type of `onClick` prop for the `HTMLButtonElement`
type OnClickType = React.HTMLAttributes<HTMLButtonElement>['onClick'] // React.MouseEventHandler<HTMLButtonElement> | undefined
// Type for a `HTMLButtonElement` with `ref` prop
type ButtonTypeWithRefType = React.DetailedHTMLProps<React.HTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
// Get type for the `white-space` CSS property: https://developer.mozilla.org/en-US/docs/Web/CSS/white-space
type WhiteSpaceType = CSS.Property.WhiteSpace // CSS.Globals | "-moz-pre-wrap" | "break-spaces" | "normal" | "nowrap" | "pre" | "pre-line" | "pre-wrap"
If you are curious about the why and how, please read on …
Why might we need type definitions for HTML and CSS?
I assume we agree that typed JavaScript in general is a good thing. But why might we need types for HTML and CSS? There are many reasons, but here are some of my common use cases:
- We want to extend the API of our custom component to support and forward a prop from a html element, like the
onClick
prop fromHTMLButtonElement
. - We want to create a custom component that supports all the props of a HTML element, like
HTMLButtonElement
, including our custom props. - We want to extend the API of our custom component to support a CSS property.
- Your using a css-in-js solution, and would like to add type checking to your css objects.
How do we use type definitions for HTML and CSS?
HTML
If we only want to pick out the type definition for one single prop, we can do as following:
// Get type of `onClick` prop for the `HTMLButtonElement`
type OnClickType = React.HTMLAttributes<HTMLButtonElement>['onClick'] // React.MouseEventHandler<HTMLButtonElement> | undefined
If we wan't the types for all the props (but without ref
!):
// Type for a `HTMLButtonElement` without `ref` prop
type ButtonType = React.HTMLAttributes<HTMLButtonElement>
If we do want the ref
prop as well, we have to specify the type like this:
// Type for a `HTMLButtonElement` with `ref` prop
type ButtonTypeWithRefType = React.DetailedHTMLProps<React.HTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
If you don't like the verbose syntax, there is a package that aliases these types, called react-html-props
:
import { ButtonProps } from "react-html-props";
// Tip: Import ButtonPropsWithoutRef if you don't care about the `ref` prop
const Button = (props: ButtonProps) => {
return <button {...props}>{props.children}</button>;
};
CSS
For css, there is the package called csstype
. To get the type of a single property, we can do as following:
import * as CSS from 'csstype';
// Get type for the `white-space` CSS property: https://developer.mozilla.org/en-US/docs/Web/CSS/white-space
type WhiteSpaceType = CSS.Property.WhiteSpace // CSS.Globals | "-moz-pre-wrap" | "break-spaces" | "normal" | "nowrap" | "pre" | "pre-line" | "pre-wrap"
For type checking an css-in-js object, we can use it like this:
import * as CSS from 'csstype';
const style: CSS.Properties = {
color: 'orangered',
textTransform: 'uppercase',
};
I've created a playground where you can experiement with these types.