Skip to content
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

JSX namespaced attribute syntax not supported #7411

Closed
JamesHenry opened this issue Mar 6, 2016 · 14 comments · Fixed by #47356
Closed

JSX namespaced attribute syntax not supported #7411

JamesHenry opened this issue Mar 6, 2016 · 14 comments · Fixed by #47356
Labels
Domain: JSX/TSX Relates to the JSX parser and emitter Suggestion An idea for TypeScript

Comments

@JamesHenry
Copy link
Contributor

TypeScript Version:

1.8.2

Background:

I have been working on trying to get https://github.com/eslint/typescript-eslint-parser, a TypeScript parser plugin for ESLint, off the ground, and the job this weekend has been to begin adding JSX support.

ESLint uses espree and so the aim of the project is to convert the output of the tsc to an AST which espree expects. We already have a solid suite of JSX tests to develop against (taken from the espree project itself), but I have come up against a tsc error in one of them so far.

My issue is that it seems currently the tsc does not accept this "namespaced attribute" JSX syntax:

Code

<a n:foo="bar"> {value} <b><c /></b></a>;

Expected behavior:
Please note the AST produced by espree (see in particular the tokens array): http://astexplorer.net/#/B46lew7I59

Actual behavior:
...compared to the one produced by the tsc (note the issues found in parseDiagnostics):
http://astexplorer.net/#/G5L3CptVNq

Removing the n: from n:foo resolves the parsing issues.

@DanielRosenwasser
Copy link
Member

Strangely, while the JSX spec draft still specifies using colons (JSXNamespacedName), facebook/react#760 (comment) specifies that dot separation ended up being the tool of choice (JSXMemberExpression).

If you try it out on Babel's converter (see here), you'll get an error:

repl: Namespace tags are not supported. ReactJSX is not XML.

So the choice is whether or not to gracefully parse and give back an error. @RyanCavanaugh, what do you think?

@JamesHenry
Copy link
Contributor Author

Thanks a lot for your digging there @DanielRosenwasser, that is really useful to know.

@nzakas, just wanted to call your attention to Daniel's points above, in case that affects anything for you with how espree or typescript-eslint-parser should handle this situation.

@nzakas
Copy link

nzakas commented Mar 7, 2016

It's important to understand that JSX is not directly tied to React, but rather is a syntax extension leveraged by React in certain ways. That's to say, just because React decides not to use some part of JSX, that doesn't mean it's removed from JSX. Namespaces are still part of the JSX spec: http://facebook.github.io/jsx/

So, this is valid JSX and should be parsed without error.

@RyanCavanaugh
Copy link
Member

We didn't support namespaced names in the JSX parser because it seemed zero people were using it (in other words, this is literally the first bug report we've gotten on it). Without any real-world use it wasn't at all clear what the semantics of it ought to be.

We'd be happy to add this support if there's some real-world use of it. If it's just for the sake of some other tool that supports it (i.e. there are no actual downstream users), we'd take a PR but wouldn't implement it ourselves.

@mhegazy mhegazy added the Suggestion An idea for TypeScript label Mar 7, 2016
@nzakas
Copy link

nzakas commented Mar 7, 2016

@RyanCavanaugh I'm interested in your use of the word "semantics" there. JSX itself has no semantics, React overlays semantics on top of it. Do I take you to mean that TypeScript has baked-in some React semantics?

@RyanCavanaugh
Copy link
Member

We haven't "baked in" anything per se -- things are mostly configurable, but the allowed range of configurations implied by the design was informed by the JSX consumers existing at the time (i.e. React and people wanting XAML-like syntax).

Since there were no consumers of JSX using the namespaced attribute syntax, we didn't implement parsing support for it since there were zero anchoring points in terms of what space of configurability to allow.

@nzakas
Copy link

nzakas commented Mar 7, 2016

Sorry, I'm not familiar with some of these terms. What sort of configurability are you referring to? And what would you expect from a pull request to implement this?

@RyanCavanaugh
Copy link
Member

See e.g. #5478 for how we do type resolution based on what interfaces and what members are in the JSX namespace.

For this issue specifically, I think we can safely say for now that namespaced attribute names do not contribute to typechecking in any way (e.g. they are not considered "error due to being surplus", and their supplied values do not have to be of any particular type). So a PR would just consist of work in the parser and preserve emitter, some very minimal work in the checker to make sure the expression values get checked (e.g. no <foo n:thing={3 * 'nope'} />), and an error in the react emitter that namespaced attributes are not supported.

If someone comes along with a framework that imposes meaningful types on these attributes, we can figure out how to add new stuff to the JSX namespace to support that.

@RyanCavanaugh
Copy link
Member

Closing until some use case for JSX namespaces shows up

@nickmessing
Copy link

@RyanCavanaugh Vue JSX uses namespace for directive arguments, any chance TypeScript could support it?
https://github.com/vuejs/jsx#directives

@snowyu
Copy link

snowyu commented Apr 22, 2019

I also hope a universal solution to embed different template, such as like markdown.

return (```pug
svg
   use(xlink:href="....")
```)


return ```xhtml
<svg><use xlink:href="..."/></svg>
```

@leops
Copy link

leops commented Oct 9, 2019

Facebook's FBT framework also uses the namespace syntax for translation parameters: <fbt:param name="username">{user.name}</fbt:param>. This is in element names and not attribute names, but the JSX specification allows JSXNamespacedName in both JSXElementName and JSXAttributeName anyway. While this is not completely blocking as the FBT library also supports a function-based syntax, the auto-parameterization feature only works with the JSX syntax.

@galaxy-s10
Copy link

@RyanCavanaugh Vue JSX 使用命名空间作为指令参数,TypeScript 有可能支持它吗?
https://github.com/vuejs/jsx#directives

非常的坑,自己用官方的@vue/babel-preset-jsx插件自己搭建脚手架,就可以解析tsx里面的jsx,包括vOn:keyup_enter这些,并且打包出来也是没问题的。但是用官方的脚手架,就解析不了tsx里面的jsx部分语法(vOn:click)

@galaxy-s10
Copy link

为什么用官方的@vue/babel-preset-jsx插件自己搭建脚手架,就可以解析tsx里面的jsx,包括vOn:keyup_enter这些,并且打包出来也是没问题的。但是用官方的脚手架,就解析不了tsx里面的jsx部分语法(vOn:click)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Domain: JSX/TSX Relates to the JSX parser and emitter Suggestion An idea for TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants