microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.29k stars 12.39k forks source link

JSX namespaced attribute syntax not supported #7411

Closed JamesHenry closed 1 year ago

JamesHenry commented 8 years ago

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 commented 8 years ago

Strangely, while the JSX spec draft still specifies using colons (JSXNamespacedName), https://github.com/facebook/react/pull/760#issuecomment-39801582 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 commented 8 years ago

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 commented 8 years ago

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 commented 8 years ago

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.

nzakas commented 8 years ago

@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 commented 8 years ago

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 commented 8 years ago

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 commented 8 years ago

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 commented 6 years ago

Closing until some use case for JSX namespaces shows up

nickmessing commented 5 years ago

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

snowyu commented 5 years ago

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 commented 4 years ago

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 commented 3 years ago

@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 commented 3 years ago

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