tsx-control-statements
Basically jsx-control-statements, but for the typescript compiler toolchain. Works for both javascript and typescript.
| Typescript version | Build status |
|---|---|
| 2.4.x | tests passing |
| 2.5.x | tests passing |
| 2.6.x | tests passing |
| 2.7.x | tests passing |
| 2.8.x | tests passing |
| 2.9.x | tests passing |
| 3.0.x | tests passing |
| 3.1.x | tests passing |
| 3.2.x | tests passing |
| 3.3.x | tests passing |
| 3.4.x | tests passing |
| next | tests passing |
It compiles tsx
- Control statements transpile to type correct typescript before type checking
- Editors like visual studio code cannot infer that some additional transpilation will occur and will complain (check out a workaround here)
- Test it:
yarn && yarn build && yarn test- Tests include behaviour compatibility tests with
jsx-control-statementsand tests whether tsx control statements render the same elements as components using plain ts in tsx.
- Tests include behaviour compatibility tests with
It compiles javascript jsx
- Setting
"allowJs"totrueintsconfig.jsonshould do the trick.
No dependence on any frontend framework
- The transformer works solely on the typescript ast and has nothing to do with React, React Native, Vue and so on. It just transforms jsx.
Known limitations:
- [js, ts] I haven't found any way of integrating this into
create-react-appscaffold project without ejecting the scripts and modifying them - [js, ts] Various CLIs (
tsc,ts-register,ts-node) feature no flag (that I know of) that allows for addition of custom transformers - [ts] The
isolatedModulesflag currently causes build errors for typescript files, since the typings currently live in a namespace - [ts] Cannot work with various "smart" plugins that instead of invoking the typescript compiler rather strip the types and handle the code as javascript. This includes tools like:
@babel/preset-typescript@babel/plugin-transform-typescript
What code is emitted?
If - Ternary operators
const SongRelatedThingy = ({ songList }: { songList: string[] }) => (
<p>
<If condition={songList.includes('Gery-Nikol - Im the Queen')}>
good taste in music
</If>
</p>
)
// will transpile to
const SongRelatedThingy = ({ songList }: { songList: string[] }) => (
<p>
{songList.includes('Gery-Nikol - Im the Queen')
? 'good taste in music'
: null
}
</p>
)With - Immediately invoked function expression
const Sum = () => (
<p>
<With a={3} b={5} c={6}>
{a + b + c}
</With>
</p>
)
// becomes
const Sum = () => (
<p>
{((a, b, c) => a + b + c))()}
</p>
)For - Array.from calls
- Since
Array.fromcan be provided with an iterator or an array-like as it's first parameter, it is much more flexible than[].map.
const Names = ({ names }: { names: string[] }) => (
<ol>
<For each="name" of={names} index="i">
<li key={name}>
{i}<strong>{name}</strong></li>
</For>
</ol>
)
// Will become
const Names = ({ names }: { names: string[] }) => (
<ol>
{Array.from(names, (name, i) => (
<li key={name}>
{i}
<strong>{name}</strong>
</li>
)}
</ol>
)Choose/When/Otherwise - Nested ternary operators.
const RandomStuff = ({ str }: { str: string }) => (
<article>
<Choose>
<When condition={str === 'ivan'}>
ivancho
</When>
<When condition={str === 'sarmi'}>
<h1>yum!</h1>
</When>
<Otherwise>
im the queen da da da da
</Otherwise>
</Choose>
</article>
)
// transpiles to
const RandomStuff = ({ str }: { str: string }) => (
<article>
{str === 'ivan'
? 'ivancho'
: (str === 'sarmi'
? React.createElement('h1', null, 'yum!')
: 'im the queen da da da da')
}
</article>
)Otherwisetag at the end is optional - if not provided, whenever noWhen's condition did match, nothing will be rendered.
Cookbook (example setups incoming)
-
- The unit test cases for this project are bundled with
fuse-box(link).
- The unit test cases for this project are bundled with
Is it a drop-in replacement of jsx-control-statements?
-
For javascript, yes.
-
This should be the case for typescript too, but I haven't tested it too much.
-
In your code:
// commonjs
const transformer = require('tsx-control-statements').default();
// ts
import transformer from 'tsx-control-statements';- If typescript complains about typings:
import 'tsx-control-statements/index.d';Reasons to not use any control statements for jsx:
- Hard to statically type
- Not part of the standard
- Not ordinary jsx elements
- Requires extra dependencies to use
- Many typescript tools do not support custom transformers in a convenient way

