# JSX and TypeScript

Source: https://signy.dev/documentation/1/overview/jsx-and-typescript/

Typed components, and JSX when you have a build step.

## TypeScript

Signy is written in TypeScript and ships its types. Signals infer their type from the first value. A component takes its props as a type parameter and marks `render()` and `setup()` as `protected`.

```js
import { Component, Signal, html } from 'signy';

interface BadgeProps {
  label: string;
}

class Badge extends Component<BadgeProps> {
  private clicks = new Signal(0);

  protected render() {
    return html`
      <button onClick=${() => this.clicks.set((c) => c + 1)}>
        ${this.props.label} (${() => this.clicks.value})
      </button>
    `;
  }
}
```

Give a signal an explicit type when the first value does not say enough.

```js
const user = new Signal<User | null>(null);
```

## JSX

JSX is compiled by `babel-plugin-jsx-dom-expressions`, the same compiler Solid uses. Calling `jsx()` at runtime throws, so setting `jsxImportSource` alone is not enough.

```js
// babel.config.js
module.exports = {
  plugins: [
    ['babel-plugin-jsx-dom-expressions', {
      moduleName: 'signy/jsx',
      generate: 'dom',
      delegateEvents: true,
      wrapConditionals: true,
    }],
  ],
};
```

With the compiler, `{count.value}` in JSX is reactive because the compiler wraps it in a function. The other rules hold: `render()` runs once and lists go through `For`.

```js
class Counter extends Component {
  private count = new Signal(0);

  protected render() {
    return (
      <button onClick={() => this.count.set((c) => c + 1)}>
        Clicked {this.count.value} times
      </button>
    );
  }
}
```
