Nov 2019
I keep struggling with setting up projects that use TypeScript, Preact and Emotion in combination. The problem is that without the proper configuration, JSX will either not be transpiled or it will call the wrong function at runtime.
Although I haven’t looked particularly deep into this I was able to
solve it. The issue stems from when you make TS aware of JSX by pointing
it to Preact’s h function instead of React.createElement but then
you need to go back and tell Emotion where to find jsx.
In order for all the transpilation to work fine with with Preact + TypeScript, you need to configure TypeScript accordingly:
// tsconfig.json
{
"compilerOptions": {
"jsx": "react",
"jsxFactory": "h"
}
}
Emotion recommends doing the following:
// .babelrc
{
"presets": ["@emotion/babel-preset-css-prop"],
"plugins": [
"emotion",
["@babel/plugin-transform-react-jsx"]
]
}
But this alone is not enough to get Emotion’s css prop working! You
will get something like jsx is undefined. So in your components your
need to tell it to use Preact’s h function as the JSX factory. You can
do that either by renaming the import or by using a pragma:
// $mycomponent.tsx
/* @jsx h */ // either this...
import { jsx as h } from '@emotion/core'; // ...or this