When using react-jsx, don't treat "key" property as special unless it's specified as IntrinsicAttribute
🔍 Search Terms
jsx, react-jsx, key property
✅ Viability Checklist
- [X] This wouldn't be a breaking change in existing TypeScript/JavaScript code
- [X] This wouldn't change the runtime behavior of existing JavaScript code
- [X] This could be implemented without emitting different JS based on the types of the expressions
- [X] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
- [X] This isn't a request to add a new utility type: https://github.com/microsoft/TypeScript/wiki/No-New-Utility-Types
- [X] This feature would agree with the rest of our Design Goals: https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals
⭐ Suggestion
When "jsx" is set to "react-jsx" the key property is missing from parameters passed to jsx function and instead is passed as separate argument. For example:
<Test param="1" key="2" />
Is compiled into:
jsx_(Test, { param: '1' }, '2')
My suggestion is to ignore this behavior unless "key" property is defined as IntrinsicAttribute.
Then, if key is not an intrinsic attribute, the example should compile into:
jsx_(Test, { param: '1', key: '2' })
📃 Motivating Example
It makes TSX more generic for use by any library, and less React specific
💻 Use Cases
This special treatment of "key" property is at odds with libraries other that react that DON'T treat key differently, making if effectively an restricted parameter.
As a workaround, you can merger parameters with key inside jsx function:
function jsx(name, params, key) {
const newParams = {...params, key};
// ...
}
But this may lead to weird special cases, like this:
<Test key="key" {...params} />
key attribute will override existing key property from params.
Please make tsx friendly for libraries other than react.
It makes TSX more generic for use by any library, and less React specific
But... you specifically asked for react-jsx...
It makes TSX more generic for use by any library, and less React specific
But... you specifically asked for
react-jsx...
If react-jsx is to be used only with react, then why don't we have "jsxImportSource" hardcoded to "react"? Or in other words, the ONLY way to use tsx for anything other than react is to set "jsx" to "preserve", because only "preserve" doesn't have the word react in it. Is that the official stance of TypeScript?
react-jsx means "compile JSX syntax using React semantics" so yes if your JSX flavor is non-React-compatible you would use preserve.
tsx for anything other than react
View frameworks exist that are not React, not React-compatible, but still are compatible only in the jsx function.
There's also the react preset for Typescript, which transforms to a function call (usually named React.createElement or h) with slightly different children semantics, and has no special semantics for key.
We don't do type-directed emit, which is what this is asking for.
jsx: react doesn't have the key special-casing; it's more accurately thought of as the JSX semantics of ~2016 that predate _jsx
jsx: react-jsx really does include React-specific semantics
jsx: preserve exists if neither of those work for your scenario
This issue has been marked as "Working as Intended" and has seen no recent activity. It has been automatically closed for house-keeping purposes.