Home

Awesome

tsx-control-statements

CI Coverage Status

NPM

Basically jsx-control-statements, but for the typescript compiler toolchain. Works for both javascript and typescript.

Typescript version rangetsx-control-statements version
2.4.x - 3.3.xv3.3.x
3.4.x - 4.6.xv4.x
4.9v5.0
5.x>= v5.1

Drop-in replacement for jsx control statements

Zero dependencies apart from typescript

Known limitations:

What are the control statements transpiled to?

If - Ternary operators

import { If } from 'tsx-control-statements/components';

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 }) => (
  <p>
    {songList.includes('Gery-Nikol - Im the Queen')
      ? 'good taste in music'
      : null}
  </p>
);

With - Immediately invoked function expression

import { With } from 'tsx-control-statements/components';

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)(3, 5, 6)}</p>;

For - Array.from calls

More flexible than [].map, since it can be provided with an iterator or an array-like as it's first parameter. For non-legacy code, prefer the more type-safe alternative.

import { For } from 'tsx-control-statements/components';

// more type-safe for, the typechecker knows
// the types of the "name" and "i" bindings
const Names = ({ names }: { names: string[] }) => (
  <ol>
    <For
      of={names}
      body={(name, i) => (
        <li key={name}>
          {i}
          <strong>{name}</strong>
        </li>
      )}
    />
  </ol>
);

// jsx-control-statements compatible
const Names = ({ names }: { names: string[] }) => (
  <ol>
    <For each="name" of={names} index="i">
      <li key={name}>
        {i}
        <strong>{name}</strong>
      </li>
    </For>
  </ol>
);

// both of the above will transpile to:
const Names = ({ names }) => (
  <ol>
    {Array.from(names, (name, i) => (
      <li key={name}>
        {i}
        <strong>{name}</strong>
      </li>
    ))}
  </ol>
);

Choose/When/Otherwise - nested ternary operators, emulates switch/case.

import {
  Choose,
  When,
  Otherwise
} from 'tsx-control-statements/components';

const RandomStuff = ({ str }: { str: string }) => (
  <article>
    <Choose>
      <When condition={str === 'ivan'}>ivancho</When>
      <When condition={str === 'sarmi'}>
        <h1>yum!</h1>
      </When>
      {/* Otherwise tag is optional,
        * if not provided, null will be rendered */}
      <Otherwise>im the queen da da da da</Otherwise>
    </Choose>
  </article>
);

// transpiles to
const RandomStuff = ({ str }) => (
  <article>
    {str === 'ivan'
      ? 'ivancho'
      : str === 'sarmi'
        ? React.createElement('h1', null, 'yum!')
        : 'im the queen da da da da'}
  </article>
);

Cookbook

Bundlers and scaffolding tools

Testing

Importing the transformer in your build configs:

// commonjs
const transformer = require('tsx-control-statements').default;

// ts
import transformer from 'tsx-control-statements';

Importing type definitions:

import {
    For,
    If,
    With,
    Choose,
    When,
    Otherwise
} from 'tsx-control-statements/components';

Reasons to not use any control statements for jsx: