GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — Add support for JSX fragment syntax by uniqueiniquity · Pull Request #19249 · microsoft/TypeScript Conversation
Contributor
Fixes #19094, which in turn reflects react/jsx#93. This PR adds support for the
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Ben Lichtman (uniqueiniquity)
requested review from
Ryan Cavanaugh (RyanCavanaugh) and
Bill Ticehurst (billti)
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just do an early return of
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changed.
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need to rename this - a fragment is an element (IMHO?)
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I take it back
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit extra newline
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed.
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reading this whole thing it seems like it'd be clearer if we wrote e.g.
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Restructured.
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reading the spec, I don't see how we'd legally get into the
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The spec changed, now you can.
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
|
| } | ||
|
|
||
| /// Either the opening tag in a <Tag>...</Tag> pair, or the lone <Tag /> in a self-closing form | ||
| /// Either the opening tag in a <Tag>...</Tag> pair, the opening tag in a <>...</> pair, or the lone <Tag /> in a self-closing form |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
This comment doesn't match our usage/terminology of isJsxOpeningLikeElement
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| } | ||
|
|
||
| // OK | ||
| let k1 = <Comp a={10} b="hi"><></><Button /><AnotherButton /></Comp>; |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
This should be a parse error
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Or perhaps we should parse it leniently but issue a grammar error in checking
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
(disregard)
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Mohamed Hegazy (@mhegazy) could you take a look at this? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Editor actions work as expected in VS and VS Code (i.e., go to def, find all references, etc are basically no-ops or return no results). I will be updating the syntax highlighter accordingly. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| // If there is no contextual type (e.g. we are trying to resolve stateful component), get attributes type from resolving element's tagName | ||
| const attributesType = getContextualType(jsxAttributes); | ||
| if (!jsxAttributes) { | ||
| return anyType; // don't check children of a fragment |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
It's better to return undefined than anyType here because it will cause the calling code to bail out earlier
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Changed.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Tracking syntax highlighter changes for VS Code at microsoft/TypeScript-TmLanguage#534. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| const tagName = createPropertyAccess( | ||
| createReactNamespace(reactNamespace, parentElement), | ||
| "Fragment" | ||
| ); |
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Should this perhaps be customizable, similar to how --jsxFactory is? e.g. --jsxFragmentComponent?
Arguably not useful for anything but React and React clones, though; as other less similar frameworks would want to do other special processing on fragments.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I agree with your second point here; to take the example of Mithril, the framework supports fragments, but with a completely different approach than React will (i.e. m.fragment(attrs, children)) so it's not as convenient as simply replacing the call to createElement with --jsxFactory. It seems to make sense in this case to just preserve the JSX syntax as is for non-React libs and have each define their own transpilation depending on their implementation of fragments.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
@Kovensky do you know what babel will do here? would it support another version of the paragma for the React.createElement?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
checked with Henry (@hzoo) over slack and does not seem that babel have plans for this in the immediate term.
I wounder if we should just make it an error to use Fragment + --jsx React + --jsxNamespace
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Ben Lichtman (@uniqueiniquity) can you file an issue for adding the error.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Oh, I think I see now. I'm confusing jsxFactory and reactNamespace
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
So are you on board with issuing the error?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Probably, but feel free not to block this PR on it.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Updated the PR to issue an error.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
In the Babel PR, I add a pragma for fragments, as Mohamed Hegazy (@mhegazy) suggested. https://github.com/babel/babel/pull/6552/files#diff-7e5b807d66ce513f501563ad8f8d03e6R117
https://github.com/babel/babel/pull/6552/files#diff-7e5b807d66ce513f501563ad8f8d03e6R89
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| } | ||
|
|
||
| // OK | ||
| let k4 = <SingleChildComp a={10} b="hi"><><Button /><AnotherButton /></></SingleChildComp>; |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I'd kinda prefer for these to be a different type like, say, JSX.Fragment, but having one would not be useful anyway without nominal typing.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
We'd like to make JSX.Element generic in the future - possibly looking it up and instantiating it based on the return type of the factory function; that would handle the Fragment case somewhat elegantly.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Generic JSX.Element<T> would be great. Outside of the React bubble, TypeScript-oriented developers like myself often wonder why the disconnect.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| "category": "Error", | ||
| "code": 17014 | ||
| }, | ||
| "Expected corresponding JSX fragment closing tag.": { |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Expected corresponding closing tag for JSX fragment.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Updated.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
|
||
| if (isJsxOpeningElement(node)) { | ||
| emitJsxTagName(node.tagName); | ||
| writeIfAny(node.attributes.properties, " "); |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
You should move this into the below if check and replace the writeIfAny with a write
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Moved.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Looks reasonable apart from the nits I requested changes on. 👍 |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| function getContextualTypeForJsxExpression(node: JsxExpression): Type { | ||
| // JSX expression can appear in two position : JSX Element's children or JSX attribute | ||
| const jsxAttributes = isJsxAttributeLike(node.parent) ? | ||
| const jsxAttributes: JsxAttributes = isJsxAttributeLike(node.parent) ? |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Why do you need this type annotation?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Removed.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.