From 48dda4db06465a62b03f7404221991cf45bb3714 Mon Sep 17 00:00:00 2001 From: Felix Kling Date: Thu, 4 Apr 2019 17:31:12 -0700 Subject: [PATCH] [flow] Resolve spread properties in object type (#339) The new fixtures shows an example that currently fails with the error ``` TypeError: Argument must be an Identifier or a Literal at getNameOrValue (/home/fkling/git/react-docgen/dist/utils/getNameOrValue.js:40:13) at getPropertyName (/home/fkling/git/react-docgen/dist/utils/getPropertyName.js:34:40) at NodePath.path.get.each.param (/home/fkling/git/react-docgen/dist/utils/getFlowType.js:171:41) at NodePath.each (/home/fkling/git/react-docgen/node_modules/ast-types/lib/path.js:89:26) at Object.handleObjectTypeAnnotation [as ObjectTypeAnnotation] (/home/fkling/git/react-docgen/dist/utils/getFlowType.js:168:26) at getFlowTypeWithResolvedTypes (/home/fkling/git/react-docgen/dist/utils/getFlowType.js:274:35) at Object.handleGenericTypeAnnotation [as GenericTypeAnnotation] (/home/fkling/git/react-docgen/dist/utils/getFlowType.js:143:14) at getFlowTypeWithResolvedTypes (/home/fkling/git/react-docgen/dist/utils/getFlowType.js:274:35) at getFlowType (/home/fkling/git/react-docgen/dist/utils/getFlowType.js:305:16) at NodePath.functionExpression.get.each.paramPath (/home/fkling/git/react-docgen/dist/utils/getMethodDocumentation.js:43:39) ``` That's because the method is referencing the `Props` type, but is not setup to deal with spread properties (like the flowTypeHandler) is. This change adds similar logic to the object type resolver. --- src/__tests__/__snapshots__/main-test.js.snap | 65 +++++++++++++++++++ src/__tests__/fixtures/component_19.js | 22 +++++++ src/utils/getFlowType.js | 10 +-- 3 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 src/__tests__/fixtures/component_19.js diff --git a/src/__tests__/__snapshots__/main-test.js.snap b/src/__tests__/__snapshots__/main-test.js.snap index 276334ece46..8dfcedd139c 100644 --- a/src/__tests__/__snapshots__/main-test.js.snap +++ b/src/__tests__/__snapshots__/main-test.js.snap @@ -1001,3 +1001,68 @@ Object { }, } `; + +exports[`main fixtures processes component "component_19.js" without errors 1`] = ` +Object { + "composes": Array [ + undefined, + ], + "description": "", + "displayName": "Component", + "methods": Array [ + Object { + "docblock": null, + "modifiers": Array [], + "name": "UNSAFE_componentWillReceiveProps", + "params": Array [ + Object { + "name": "nextProps", + "optional": undefined, + "type": Object { + "alias": "Props", + "name": "signature", + "raw": "{| + data?: Array, + ...React.ElementConfig, +|}", + "signature": Object { + "properties": Array [ + Object { + "key": "data", + "value": Object { + "elements": Array [ + Object { + "name": "mixed", + }, + ], + "name": "Array", + "raw": "Array", + "required": false, + }, + }, + ], + }, + "type": "object", + }, + }, + ], + "returns": null, + }, + ], + "props": Object { + "data": Object { + "description": "", + "flowType": Object { + "elements": Array [ + Object { + "name": "mixed", + }, + ], + "name": "Array", + "raw": "Array", + }, + "required": false, + }, + }, +} +`; diff --git a/src/__tests__/fixtures/component_19.js b/src/__tests__/fixtures/component_19.js new file mode 100644 index 00000000000..736ab4b50e4 --- /dev/null +++ b/src/__tests__/fixtures/component_19.js @@ -0,0 +1,22 @@ +import React from 'react'; + +type Props = {| + data?: Array, + ...React.ElementConfig, +|}; + +type State = {| + width: number, +|}; + +export default class Component extends React.PureComponent { + UNSAFE_componentWillReceiveProps(nextProps: Props) { + doSomething(); + } + + render() { + return ( +
Hello
+ ); + } +} diff --git a/src/utils/getFlowType.js b/src/utils/getFlowType.js index 0527ebf25b6..a75a49400b1 100644 --- a/src/utils/getFlowType.js +++ b/src/utils/getFlowType.js @@ -161,10 +161,12 @@ function handleObjectTypeAnnotation(path: NodePath): FlowTypeDescriptor { }); path.get('properties').each(param => { - type.signature.properties.push({ - key: getPropertyName(param), - value: getFlowTypeWithRequirements(param.get('value')), - }); + if (types.ObjectTypeProperty.check(param.node)) { + type.signature.properties.push({ + key: getPropertyName(param), + value: getFlowTypeWithRequirements(param.get('value')), + }); + } }); return type;