Skip to content

Add section for TSX #36

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open

Conversation

JodliDev
Copy link

Description

This change adds a new section that describes the setup of TSX (JSX for Typescript) including some additional configurations that should solve all (most?) problems with TSX.

Motivation and Context

There is no official documentation on how to set up JSX in Typescript and other resources often target outdated versions of MithrilJS. There are also a few pitfals that are not trivial to solve.
I wrote up what I have found and implemented for myself. Hopefully this is usefull (and wanted) in the documentation as well :)

Copy link
Member

@dead-claudia dead-claudia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay. It took about an hour for me to go through this PR, because of all the feedback needed on it.

I do appreciate the effort. And I've been through worse early in my time with open source, so I completely understand how it may feel to be suddenly blasted with large amounts of feedback like that.

docs/jsx.md Outdated

The simplest way to use JSX is via a [Babel](https://babeljs.io/) plugin.
When using JavaScript, the simplest way to use JSX is via a [Babel](https://babeljs.io/) plugin. When using using [TypeScript](https://www.typescriptlang.org/) follow the [instructions below](#setup-tsx-jsx-in-typescript)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's move the "when using TypeScript" to the next section.

Suggested change
When using JavaScript, the simplest way to use JSX is via a [Babel](https://babeljs.io/) plugin. When using using [TypeScript](https://www.typescriptlang.org/) follow the [instructions below](#setup-tsx-jsx-in-typescript)
When using JavaScript, the simplest way to use JSX is via a [Babel](https://babeljs.io/) plugin.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I shortened it. But I do think its wise to link to TSX in this secion. A lot of times the term "JSX" is used for "TSX" interchangably (so is "JavaScript" for "TypeScript") and TypeScript users might stumble over this section and follow the wrong instructions. Tell me if you find that unnecessary and I should fully remove it

@JodliDev
Copy link
Author

JodliDev commented Aug 9, 2025

I incorporated your suggestions. Let me know if you notice other problems / improvements.

No worries about the amount of feedback. I do apreciate you being thorough :)

Copy link
Member

@dead-claudia dead-claudia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In addition to the other comments, we avoid unnecessary semicolons in the docs in the same way we do in core. I decided it was better to raise it here than to just spam even more comments (it's already over 20 for this one review).


The simplest way to use JSX is via a [Babel](https://babeljs.io/) plugin.
When using JavaScript, the simplest way to use JSX is via a [Babel](https://babeljs.io/) plugin. (For TypeScript follow the [instructions below](#setup-tsx-jsx-in-typescript)).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Grammar nit

Suggested change
When using JavaScript, the simplest way to use JSX is via a [Babel](https://babeljs.io/) plugin. (For TypeScript follow the [instructions below](#setup-tsx-jsx-in-typescript)).
When using JavaScript, the simplest way to use JSX is via a [Babel](https://babeljs.io/) plugin. (For TypeScript, follow the [instructions below](#setup-tsx-jsx-in-typescript).)

@@ -58,9 +60,9 @@ m.render(document.body, <MyComponent />)

---

### Setup
### Setup JSX
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The TypeScript docs call it JSX, so I'd prefer to stick with that idiom for both.

Suggested change
### Setup JSX
### Setup for JavaScript

Comment on lines +246 to +248
### Setup TSX (JSX in TypeScript)

When using [TypeScript](https://www.typescriptlang.org/), all you need to do is tell TypeScript how to handle JSX code correctly. Since TypeScript can transpile JSX and TSX on its own, you don't need any other tools like Babel to do it for you. (More information can be found about JSX in TypeScript [here](https://www.typescriptlang.org/docs/handbook/jsx.html).)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See earlier regarding TypeScript and JSX. Also, in your parenthetical, it's pretty obvious from context we're talking about JSX in TypeScript, so we don't need to repeat ourselves there.

Suggested change
### Setup TSX (JSX in TypeScript)
When using [TypeScript](https://www.typescriptlang.org/), all you need to do is tell TypeScript how to handle JSX code correctly. Since TypeScript can transpile JSX and TSX on its own, you don't need any other tools like Babel to do it for you. (More information can be found about JSX in TypeScript [here](https://www.typescriptlang.org/docs/handbook/jsx.html).)
### Setup for TypeScript
When using [TypeScript](https://www.typescriptlang.org/), all you need to do is tell TypeScript how to handle JSX code correctly. Since TypeScript can transpile JSX on its own, you don't need any other tools like Babel to do it for you. (More information can be found [here](https://www.typescriptlang.org/docs/handbook/jsx.html).)

This setup should be enough to get most JSX functionality working.

#### Using closure components in TSX
>Because of https://github.com/microsoft/TypeScript/issues/21699, we advise against using [closure components](components.md#closure-component-state) in TypeScript for now. Either use [class components](components.md#class-component-state) without attribute inspection or Hyperscript instead (see the list of alternatives below the code example).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion to clean this up and elaborate on the recommendation better. Also, we usually keep spaces after Markdown block-level syntax like > and #, and this suggestiin factors that in.

If there's anything you feel is unclear or you disagree with, feel free to comment here on it.

Suggested change
>Because of https://github.com/microsoft/TypeScript/issues/21699, we advise against using [closure components](components.md#closure-component-state) in TypeScript for now. Either use [class components](components.md#class-component-state) without attribute inspection or Hyperscript instead (see the list of alternatives below the code example).
> Because [TypeScript does not, at the time of writing, allow customizing the type used to check JSX component validity](https://github.com/microsoft/TypeScript/issues/21699), we recommend you avoid using [closure components](components.md#closure-component-state) as JSX component names in TypeScript for now. Either use [class components](components.md#class-component-state) exclusively or use [hyperscript](hyperscript.md) to construct them.
>
> You'll see what we mean after reading this section. It's not simple to work around TypeScript's missing feature here.

```

There are several options to circumvent that problem:
1. Instead of `<div><ChildComponent greet="Hello World"/></div>`, use `<div>{m(ChildComponent, {greet: "Hello World"})}</div>` instead.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion to clarify this a bit better.

Suggested change
1. Instead of `<div><ChildComponent greet="Hello World"/></div>`, use `<div>{m(ChildComponent, {greet: "Hello World"})}</div>` instead.
1. Instead of `<div><ChildComponent greet="Hello World"/></div>`, use [hyperscript](hyperscript.md) instead: `<div>{m(ChildComponent, {greet: "Hello World"})}</div>`.

}
function ChildComponent(vNode: Vnode<Attributes>): m.Component<Attributes> {
return {
view: <div>{vNode.attrs.greet}</div>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
view: <div>{vNode.attrs.greet}</div>
view: () => <div>{vNode.attrs.greet}</div>


function ParentComponent() {
return {
view: () => <div><ChildComponent greet="Hello World"/></div>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same readability fix.

Suggested change
view: () => <div><ChildComponent greet="Hello World"/></div>
view: () => <div>
<ChildComponent greet="Hello World"/>
</div>


```
TS2739: Type { greet: string; } is missing the following properties from type Vnode<{}, {}>: tag, attrs, state
TS2786: LoadingSpinner cannot be used as a JSX component.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
TS2786: LoadingSpinner cannot be used as a JSX component.
TS2786: ChildComponent cannot be used as a JSX component.


For example, if you try to compile this code:

```typescript jsx
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
```typescript jsx
```tsx


The following code will work without errors:

```typescript jsx
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
```typescript jsx
```tsx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants