Using JSX in TypeScript without React

Viewed 4924

What is a simple way to have TypeScript recognize JSX (especially in VS Code) without having React as a dependency? If we have to use a custom JSX namespace and a custom renderer, then what is the expected shape of the contents of that namespace and the renderer?

As far as I know, JSX is just syntactic sugar that is transformed into function calls (e.g., React.createElement), so there should be a way to specify that a different function should be used for transforming the JSX.

Looking at the release docs for TypeScript 2.8, I see there are sections titled "Per-file JSX factories" and "Locally scoped JSX namespaces", but I don't see these sections in the official current TypeScript docs. Have these features been deprecated?

2 Answers

jsx and jsxFactory compiler options are responsible for that.

TypeScript expects a function defined in jsxFactory to exist in module scope. Usually this requires to import React because jsxFactory defaults to React.createElement.

If the compiler is configured with:

...
"jsx": "react",
"jsxFactory": "h",
...

Then h function should exist. JSX-related types should be defined to make type checks work properly:

declare namespace JSX {
  interface Element {}
  interface ElementClass {
    render(): any;
  }
  interface IntrinsicElements {
    div: any;
    // ...
  }
}

const h = (Comp: any): any => console.log(`creating ${Comp} element`);

<div/>;

class FooComponent {
  render = () => null;
}

<FooComponent/>;

The Typescript compiler has flags that allow you to specify how TSX/JSX is handled.

Specifically, you have to specify "--jsx=React" and "--jsxFactory=someModule.yourJsxFactory", and in your tsx files, you supply your custom factory by importing "someModule", from which "yourJsxFactory" should be exported.

Read more about it at
Typescript (Compiler Options)
and
Typescript (JSX)

Related