Description
Hi! 👋
Firstly, thanks for your work on this project! 🙂
I have a file which exports a regular function
who's first parameter is an object, plus a React function component with a defined displayName
. When these conditions are met, the component's props are not output in the final result.
The minimum reproduction is:
export const Button = ({ label }: { label: string }) => (
<button>{label}</button>
);
Button.displayName = 'Button';
export function areButtonsAwesome(obj = {}) {}
It appears the getTextValueOfFunctionProperty
method is scanning the source file to generate display name's for each function by searching for the .displayName =
assignment within the complete source file.
The issue occurs because it does not take into account the function on which the .displayName
is being set; in the example above, both Button
and areButtonsAwesome
will end up with a displayName of Button
thanks to the line Button.displayName = 'Button'
. This on its own isn't an issue until later code deduplicates based on the generated displayName
. In this case, the areButtonsAwesome
wins, and Button
is removed from the output as the "duplicate".
The fix is to check the .displayName
is being assigned to the function in question, instead of just using the first one found.
Here is the diff that solved my problem:
diff --git a/node_modules/react-docgen-typescript/lib/parser.js b/node_modules/react-docgen-typescript/lib/parser.js
index e98cd64..09dc39e 100644
--- a/node_modules/react-docgen-typescript/lib/parser.js
+++ b/node_modules/react-docgen-typescript/lib/parser.js
@@ -797,7 +797,17 @@ function getTextValueOfFunctionProperty(exp, source, propertyName) {
return (expr.left &&
expr.left.name &&
expr.left.name.escapedText ===
- propertyName);
+ propertyName &&
+ // Ensure the .displayName is for the function we're processing. This
+ // avoids a situation where a file has multiple functions, only one of
+ // which has a .displayName; we don't want all functions inheriting that
+ // value by mistake.
+ statement.flowNode &&
+ statement.flowNode.node &&
+ statement.flowNode.node.name &&
+ statement.flowNode.node.name.escapedText &&
+ statement.flowNode.node.name.escapedText === exp.escapedName
+ );
})
.filter(function (statement) {
return ts.isStringLiteral(statement
I'm not sure how to write this in TS, perhaps you can take my patch and apply it to the .ts
file manually?
This issue body was partially generated by patch-package.