hegel icon indicating copy to clipboard operation
hegel copied to clipboard

Hegel and JSX

Open unrealsolver opened this issue 5 years ago • 13 comments

How could we accomplish Hegel to work with JSX?

unrealsolver avatar Mar 02 '20 15:03 unrealsolver

Currently, Hegel doesn't work with JSX, but it will work

JSMonk avatar Mar 02 '20 21:03 JSMonk

If Hegel adopts JSX (which would be awesome!), please take a look at these TypeScript issues:

  • https://github.com/microsoft/TypeScript/issues/14729
  • https://github.com/microsoft/TypeScript/issues/21699
  • https://github.com/microsoft/TypeScript/issues/3788
  • https://github.com/Microsoft/TypeScript/issues/20469

The TLDR of those issue is that JSX is merely a language feature, and various tools and libraries give JSX different meaning.

Some tools, for example, compile JSX to DOM expressions. In the statement

const div = <div>hello</div>
const div = <p><span>world</span></p>

it would be great to be able to configure Hegel (either with types in code or specifying types in a config file, or something) so that the div variable is inferred to be of type HTMLDivElement and p is inferred to be of type HTMLParagraphElement.

To take the idea further, maybe there could be (for exampe), a type error if a HTMLSelectElement is passed children that aren't HTMLOptionElement or HTMLOptGroupElement.

In TypeScript currently, JSX expressions have only one type, JSX.Element (which can be defined in the environment by the TypeScript user, and the react lib defines it if you have it installed), and the JSX mechanism is generally geared towards React and React-like vdom-factory libs.

If Hegel will add JSX, there's a chance here to do it a better way than with TypeScript, making it more generic and useful for a variety of use cases.

cc @ryansolid

trusktr avatar May 20 '20 05:05 trusktr

@trusktr. Thank you a lot ❤️ . It will really help us to implement better JSX support.

JSMonk avatar May 20 '20 11:05 JSMonk

Framework-agnostic JSX would be so nice! You might not want to overload this feature, but, here's another use-case: https://emotion.sh/docs/css-prop tl;dr; it's currently possible in TS to augment JSX.IntrinsicAttributes or similar interfaces in order to add global props, which are expected to be transformed by a macro or plugin. The props that actually get rendered might not be the same as the ones written in the source. Using the css prop in your source might result in using className at runtime...so it might get dicey in terms of type soundness...maybe it's just not worth the trouble.

dmisdm avatar Jun 11 '20 05:06 dmisdm

We can make the same assumption with JSX output as with any other JS output from TS: people will write JSX (or JS) with type safety, and then view the result in the browser, without muddling with the output. They will rely on TS type checking the source, without caring about the output.

trusktr avatar Jun 15 '20 20:06 trusktr

we can just add @babel/plugin-transform-react-jsx plugin and most of jsx will work without much effort

also type system will have same behaviour on jsx and React.createElement code

Screen Shot 2020-06-22 at 07 33 38

thecotne avatar Jun 22 '20 03:06 thecotne

Yeah.. although I believe that brings most of the React-isms with it. It's a path. But it feels like TypeScript has been spending the last couple years trying to backtrack from those early only consider React decisions. The JSX spec goes well beyond what React uses and that transformation. Things like attribute namespaces come to mind (which would be really useful for Vue or Svelte like templating). Or even how awkward it has been to add a universal approach to fragments. The quite literally goes on and on.

ryansolid avatar Jun 22 '20 04:06 ryansolid

@ryansolid if we make plugins used by hegel configurable we can support any number of frameworks/libraries

for example with babel-plugin-jsx-dom-expressions we can support DOM Expressions like so

Screen Shot 2020-06-22 at 08 06 10

thecotne avatar Jun 22 '20 04:06 thecotne

we can just add @babel/plugin-transform-react-jsx plugin and most of jsx will work without much effort

Add it to Hegel? Or add it to an app's particular build pipeline?

I think it would be neat if a tool like Hegel had Babel support built in (to some degree?), so we could have both type safety and choice of (JSX) output all in one tool.

trusktr avatar Jul 01 '20 02:07 trusktr

@trusktr hegel is using babel parser and babel AST so babel plugins can be used as well

thecotne avatar Jul 01 '20 11:07 thecotne

As far as I understand, Hegel’s model is very close to Flow’s one: it provides the type system only relying on Babel build pipeline to transpile the code for use in browsers and node.

Btw, while using Flow I always missed the support for Babel plugins at the type level. This blocked my team from experimenting with cutting edge language features and making our own little tweaks (say for testing).

peter-leonov avatar Jul 01 '20 11:07 peter-leonov

@JSMonk I think it's best to let handle JSX to a well established tools like babel via webpack or alike and provide only type checks.

hinell avatar Jul 12 '20 20:07 hinell

@JSMonk I think it's best to let handle JSX by a well established tools like babel via webpack or alike and provide only type checks.

Considering Hegel already uses Babel, maybe Hegel can just add a config option that allows the user to specify Babel presets/plugins that are used after Hegel has finished type checking and after Hegel's transform. Or maybe Hegel can only strip types (after type checking), and allow the user to specify all of the Babel transforms (overriding the default).

trusktr avatar Aug 04 '20 21:08 trusktr