diff --git a/src/__tests__/data/FunctionDeclarationDefaultProps.tsx b/src/__tests__/data/FunctionDeclarationDefaultProps.tsx
new file mode 100644
index 00000000..65d71321
--- /dev/null
+++ b/src/__tests__/data/FunctionDeclarationDefaultProps.tsx
@@ -0,0 +1,16 @@
+import * as React from 'react';
+
+interface FunctionDeclarationDefaultPropsProps {
+ id?: number;
+}
+
+/** FunctionDeclarationDefaultProps description */
+export const FunctionDeclarationDefaultProps = (
+ props: FunctionDeclarationDefaultPropsProps
+) => {
+ return
Hello World
;
+};
+
+FunctionDeclarationDefaultProps.defaultProps = {
+ id: 1
+};
diff --git a/src/__tests__/parser.ts b/src/__tests__/parser.ts
index cd93c394..1dd6aa4a 100644
--- a/src/__tests__/parser.ts
+++ b/src/__tests__/parser.ts
@@ -350,6 +350,19 @@ describe('parser', () => {
});
});
+ it('should parse react stateless component default props when declared as a normal function', () => {
+ check('FunctionDeclarationDefaultProps', {
+ FunctionDeclarationDefaultProps: {
+ id: {
+ defaultValue: 1,
+ description: '',
+ required: false,
+ type: 'number'
+ }
+ }
+ });
+ });
+
it('should parse react stateless component with external intersection props', () => {
check('StatelessIntersectionExternalProps', {
StatelessIntersectionExternalProps: {
diff --git a/src/parser.ts b/src/parser.ts
index 0e39d1a9..fe0948fb 100644
--- a/src/parser.ts
+++ b/src/parser.ts
@@ -137,7 +137,9 @@ export function withCustomConfig(
if (error !== undefined) {
// tslint:disable-next-line: max-line-length
- const errorText = `Cannot load custom tsconfig.json from provided path: ${tsconfigPath}, with error code: ${error.code}, message: ${error.messageText}`;
+ const errorText = `Cannot load custom tsconfig.json from provided path: ${tsconfigPath}, with error code: ${
+ error.code
+ }, message: ${error.messageText}`;
throw new Error(errorText);
}
@@ -631,23 +633,20 @@ export class Parser {
symbol: ts.Symbol,
source: ts.SourceFile
) {
- let possibleStatements = source.statements
- // ensure that name property is available
- .filter(stmt => !!(stmt as ts.ClassDeclaration).name)
- .filter(
- stmt =>
- this.checker.getSymbolAtLocation(
- (stmt as ts.ClassDeclaration).name!
- ) === symbol
- );
-
- if (!possibleStatements.length) {
- // if no class declaration is found, try to find a
- // expression statement used in a React.StatelessComponent
- possibleStatements = source.statements.filter(
+ let possibleStatements = [
+ ...source.statements
+ // ensure that name property is available
+ .filter(stmt => !!(stmt as ts.ClassDeclaration).name)
+ .filter(
+ stmt =>
+ this.checker.getSymbolAtLocation(
+ (stmt as ts.ClassDeclaration).name!
+ ) === symbol
+ ),
+ ...source.statements.filter(
stmt => ts.isExpressionStatement(stmt) || ts.isVariableStatement(stmt)
- );
- }
+ )
+ ];
return possibleStatements.reduce((res, statement) => {
if (statementIsClassDeclaration(statement) && statement.members.length) {
@@ -683,9 +682,9 @@ export class Parser {
let propMap = {};
if (properties) {
- propMap = this.getPropMap(
- properties as ts.NodeArray
- );
+ propMap = this.getPropMap(properties as ts.NodeArray<
+ ts.PropertyAssignment
+ >);
}
return {
@@ -699,9 +698,9 @@ export class Parser {
if (right) {
const { properties } = right as ts.ObjectLiteralExpression;
if (properties) {
- propMap = this.getPropMap(
- properties as ts.NodeArray
- );
+ propMap = this.getPropMap(properties as ts.NodeArray<
+ ts.PropertyAssignment
+ >);
}
}
});
@@ -709,6 +708,7 @@ export class Parser {
...res,
...propMap
};
+ } else {
}
const functionStatement = this.getFunctionStatement(statement);
@@ -788,26 +788,31 @@ export class Parser {
public getPropMap(
properties: ts.NodeArray
): StringIndexedObject {
- const propMap = properties.reduce((acc, property) => {
- if (ts.isSpreadAssignment(property) || !property.name) {
- return acc;
- }
-
- const literalValue = this.getLiteralValueFromPropertyAssignment(property);
- const propertyName = getPropertyName(property.name);
+ const propMap = properties.reduce(
+ (acc, property) => {
+ if (ts.isSpreadAssignment(property) || !property.name) {
+ return acc;
+ }
- if (
- (typeof literalValue === 'string' ||
- typeof literalValue === 'number' ||
- typeof literalValue === 'boolean' ||
- literalValue === null) &&
- propertyName !== null
- ) {
- acc[propertyName] = literalValue;
- }
+ const literalValue = this.getLiteralValueFromPropertyAssignment(
+ property
+ );
+ const propertyName = getPropertyName(property.name);
+
+ if (
+ (typeof literalValue === 'string' ||
+ typeof literalValue === 'number' ||
+ typeof literalValue === 'boolean' ||
+ literalValue === null) &&
+ propertyName !== null
+ ) {
+ acc[propertyName] = literalValue;
+ }
- return acc;
- }, {} as StringIndexedObject);
+ return acc;
+ },
+ {} as StringIndexedObject
+ );
return propMap;
}