Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
jsx-eslint#969 fix: exception for jsx-no-duplicate-props
jsx-no-duplicate-props is causing error. TypeError: name.toLowerCase is not a function. When <Element {...props}> is used.
- Loading branch information
6918bba
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.
@marcelmokos @DianaSuvorova
This change is a workaround, not a fix. This line below
props[name] = 1;
will evaluate toprops["[object Object]"] = 1;
that is not intended.The right change would be to handle the string and the object cases for all the code below the
var name = decl.name.name;
.What AST node stands for the object in the
decl.name.name
?6918bba
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.
The problem is that when the code is invalid it creates an error that makes no sense.
Currently, the fix is sufficient. You are proposing to implement a recursive function to find a name that is actually a string in the nested object.
6918bba
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.
I'm proposing to at least wrap every line of code that is data-dependent on the
name
variable into the type check you introduced.6918bba
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.
@marcelmokos This will prevent further lines that depend on
name
being astring
from running.6918bba
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.
@marcelmokos Oh I see what you mean.
So proposed test case might be something like:
With your change linter will skip both invalid JSX instances. With the original change it may report
'No duplicate props allowed' because it will consider
"[object Object]"
props duplicated.@marcelmokos do you want to take care of updating your code and creating a PR?
6918bba
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.
@DianaSuvorova Exactly. Sorry it was hard for me to type such test cases from a phone.
I also think not seeing data flows and strict type errors in JavaScript is the cause for such patchy fixes. If this were written in TypeScript or with other typechecking, be it Flow or Elm, the compiler/linter would immediately say that the type of
name
can beobject
orstring
but the variable is always used as astring
.This can be inferred from the ESTree JSXOpeningElement specification:
attributes: [ESTree.JSXAttribute.t | ESTree.JSXSpreadAttribute.t]
, so that an element of thenode.attributes
array, which isdecl
, is of typeESTree.JSXAttribute.t | ESTree.JSXSpreadAttribute.t
,JSXSpreadAttribute
type withif (decl.type === 'JSXSpreadAttribute') { return; }
,decl
being of typeJSXAttribute
, for whichname: ESTree.JSXIdentifier.t | ESTree.JSXNamespacedName.t
(that is ourdecl.name
),decl.name
is of typeESTree.JSXIdentifier.t | ESTree.JSXNamespacedName.t
which has two cases:decl.name
isJSXIdentifier
, then it hasname: binary
β this is ourdecl.name.name
being astring
case)decl.name
isJSXNamespacedName
then it hasname: ESTree.JSXIdentifier.t
β this is ourdecl.name.name
being anobject
(theJSXIdentifier
AST node).6918bba
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.
Edited 6918bba#commitcomment-23209210 β fixed a typo in the type inference explanation.