Razor For Typescript

I recently discovered and fell in love with Razor. Razor is a templating language based on HTML (or XML) and C# (or VB) and looks like this:

<html>
<body>
Hello, world! Here's a list of stuff:
<ul>
@foreach (var i in someArray) {
  <li>@i</li>
}
</ul>
</body>
</html>

The great advantage of Razor over other templating languages seen in the wild is that Razor is 100% type-safe and checked at compile-time; with the appropriate environments, one can even get syntax highlighting and code navigation just like in “real code”. The great disadvantage is that it’s .NET only, which made it unavailable for my TypeScript project. I was stuck with Nunjucks, which isn’t type-safe, and therefore loses the main benefit of TypeScript in a big chunk of my code.

Enter React. I don’t care much for the framework (in fact, I don’t use it in my project), but React created the language known as JSX, or when combined with TypeScript, TSX. When combined with a small bit of boilerplate, this is valid TSX:

function foo(someArray: string[]) {
  return <html>
  <body>
  Hello, world! Here's a list of stuff:
  <ul>
  { someArray.map(i => <li>{i}</li>) }
  </ul>
  </body>
  </html>;
}

The boilerplate in question needs to define a some elements and their attributes, and a React.createElement function. My example is pretty hacky, but it exists as noreact.js. With this, the following is valid and produces an HTML string:

import * as React from './noreact';

function foo(someArray: string[]) { ... }

console.log(foo(['one', 'two', 'three']));

Don’t forget to npm install array-flatten, and run with ts-node -O '{"jsx": "React"}' to enable TSX.