3

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
  • Possible duplicate of can i use jsx without React to inline html in script? Commented Jan 11, 2019 at 10:12
  • 1
    @Berr'ita: This is not a duplicate. I specifically indicated out I want to use TypeScript in VSCode (to retain the intellisense features). The other question talks about babel plugins and third-party packages, which I don't want Commented Jan 11, 2019 at 10:43

2 Answers 2

4

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/>;
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks @estus: Does this mean that all components you define have to be added to the JSX.IntrinsicElements structure? Can you provide an example of defining a custom component that will be recognized by this scheme?
Not exactly. IntrinsicElements are for HTML and SVG. You can use React's own types as starting point, github.com/DefinitelyTyped/DefinitelyTyped/blob/…
Can you actually provide a code snippet of a custom non-react component that is type-checked by TypeScript? It seems that is the best way to get at the problem I am having
Ok @estus, what about functional components? I've tried them and they mostly work, but sometimes there are some weird type errors. For example, const FComp = () => <div/> gives an error, but const FComp = () => {return <div/> } does not
Also @estus, evaluating <FComp /> by itself gives an error, but let elt = <FComp /> does not
|
1

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)

10 Comments

@Kaldestad: I have read those documents, and I still have specific questions. If you can provide a specific answer to my questions, I would appreciate that
@prmph It's a bit weird that you have to specify "--jsx=React" when you specifically want jsx to be handled NOT by React, but that's the way the cookie crumbles
@prmph I've added some further specification to my answer now
@ Kaldestad: Yes, the "jsx:"react" bit is confusing. Also, there is more to this than the docs explain. For example, what is the expected shape of the JSX.IntrinsicElements types?
@prmph Maybe that's a bit unclear in the docs, I agree. I've found @types/react on github to be a good guide. In essence, it should provide type information for the "official" html elements. Or not, you can choose to omit it entirely as stated in the docs.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.