-
-
Notifications
You must be signed in to change notification settings - Fork 3
Add JSX support in type definition #3
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
Conversation
Huh, interesting! The unist-builder/hastscript/xastscript signatures are indeed designed to be somewhat like The new JSX transform in React 17 is in my opinion nice for React, but unfortunate for anyone else who handles JSX. For example, it’s React-specific that Code-wise, some of the comment are still missing, or read a bit confusing to me. There should be tests for members in tag names: Should we somehow handle fragments too? Turn into roots? Only makes sense when it‘s the outer thing, and should be extracted when occurring as a child, and thrown on when having props? 🤔 JSX allows tags/fragments as attribute values too: |
If we’re going to do this, it’d be wise to have actual checks for it in the tests too. But that could be a different PR. And we’d check acorn and others to see how they handle JSX. |
My thought exactly! :D
Only one JSX pragma can be used per file. I think this might be interesting for
I agree. Let’s forget about this. :)
Type definitions for JSX are super confusing. Also JSX type definitions don’t line up with how JSX can be used in React or Preact.
I wanted to check if you think this is a good idea before continueing this. 😃
There is a test for props (
See below.
This is disallowed by the
This would mean the tests need to be processed by Babel or TypeScript. This doesn’t mean it can’t be done.
Acorn is a JavaScript parser. I don’t see why we should look how they handle JSX. I’ll try to give a brief explanation of what JSX is. The following 2 blocks of code are identical: /** @jsx x */
import * as x from 'hastscript';
function Component() {}
x('foo', null);
x('foo', { bar: 'baz' });
x('foo', null, x('bar', null), x('baz', null))
x(Component, null);
<foo />
<foo bar="baz" />
<foo>
<bar />
<baz />
</foo>
<Component /> JSX tag names matching In TypeScript, the A functional component is a library specific implementation detail. The actual call signature depends on the implementing library. In React, a functional component is a function that has the following signature: type ReactNode = string | number | boolean | null | JSX.Element | Array<ReactNode>;
function MyComponent(props?: ObjectLikeInterface): ReactNode; In TypeScript, a functional component is a function that has the following signature: function MyComponent(props?: ObjectLikeInterface): JSX.Element; This is a bug in TypeScript. The return type of functional components should match the same type as the return value of the JSX implementation, which isn’t true for React and other libraries. A fragment is a functional component that takes no props (or optional props only), whose name is marked as fragment. This means adding support for fragments actually means adding support for functional components. /** @jsxFrag Foo */
// This is a fragment now.
function Foo() {
return <div />
}
// yields <div></div>
<></> Typically a fragment is used to return wrapped children. For a fragment implementation Now the explanations of the added type definitions:
|
This PR tests that `xastscript` can be used as the pragma for JSX with bublé and babel. Code-wise, this adds support for using `x` to generate root nodes. This is done by omitting the tag name (like so: `x()`, `x(null, 'child')`). Previously, omitting a `name` resulted in an exception. Another aspect of supporting JSX is supporting fragments as children. As fragments yield root nodes, we unravel them and use only their children. While this could be seen a change, xast prohibits roots occurring in nodes, so the unraveling instead fixes what would otherwise be a broken tree. Related to: GH-3.
See GH-4! |
This PR tests that `xastscript` can be used as the pragma for JSX with bublé and babel. Code-wise, this adds support for using `x` to generate root nodes. This is done by omitting the tag name (like so: `x()`, `x(null, 'child')`). Previously, omitting a `name` resulted in an exception. Another aspect of supporting JSX is supporting fragments as children. As fragments yield root nodes, we unravel them and use only their children. While this could be seen a change, xast prohibits roots occurring in nodes, so the unraveling instead fixes what would otherwise be a broken tree. Related to: GH-3.
This PR tests that `xastscript` can be used as the pragma for JSX with bublé and babel. Code-wise, this adds support for using `x` to generate root nodes. This is done by omitting the tag name (like so: `x()`, `x(null, 'child')`). Previously, omitting a `name` resulted in an exception. Another aspect of supporting JSX is supporting fragments as children. As fragments yield root nodes, we unravel them and use only their children. While this could be seen a change, xast prohibits roots occurring in nodes, so the unraveling instead fixes what would otherwise be a broken tree. Related to: GH-3. Reviewed-by: Christian Murphy <[email protected]>
This change tests that `hastscript` can be used as the pragma for JSX with bublé and babel. Code-wise, this adds support for using `h` to generate root nodes. This is done by omitting the tag name (like so: `h()`, `h(null, 'child')`). Previously, omitting a `name` resulted in the default element to be created (`div` for `h`, `g` for `s`). This change thus is a breaking change. The old behavior is still available when passing an empty string: `h('')`. Another aspect of supporting JSX is supporting fragments as children. As fragments yield root nodes, we unravel them and use only their children. While this could be seen a change, hast prohibits roots occurring in nodes, so the unraveling instead fixes what would otherwise be a broken tree. Related to: syntax-tree/xastscript#3. Related to: syntax-tree/xastscript#4.
switching to semver patch, since this was added as a feature in #4, this now catches the type definitions up to the implementation |
...soooo, which one should we go with? Both are failing 🤷♂️ Anything unresolved things? Other ways I can help? |
Co-authored-by: Titus <[email protected]>
This means the type of `hastscript.JSX.Element` had to be changed to `xast.Element | xast.Root`. This also means a minimum TypeScript version of 4.0 is required to test types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @remcohaszing!
It’s value is not supposed to be used.
Ping @wooorm I think this can be merged and released 😄 |
thanks, released! |
This adds TypeScript support to use
xastscript
as JSX. This is just an idea. It’s definitely open for discussion. :)The interface already supports JSX legacy mode, meaning this was already supported, except for types.
I don’t know if this was intended. Basically any function that accepts a tag name as first argument, props as second argument, and children as spread arguments, can be considered a JSX compatible function. I figured for
xastscript
it makes sense, because it’s for working with XML.Some quirks: