Eslint-plugin-react: TypeError: Cannot read property 'type' of undefined

Created on 15 Sep 2020  ยท  3Comments  ยท  Source: yannickcr/eslint-plugin-react

eslint-plugin-react v7.20.6 causes the following error:

```Oops! Something went wrong! :(

ESLint: 7.6.0 (or 7.9.0)

TypeError: Cannot read property 'type' of undefined
Occurred while linting /path-to-file/Component.tsx:101
at Object.isRequiredPropType (/node_modules/eslint-plugin-react/lib/util/props.js:91:29)
at /node_modules/eslint-plugin-react/lib/util/propTypes.js:669:54
at iterateProperties (/node_modules/eslint-plugin-react/lib/util/propTypes.js:64:7)
at /node_modules/eslint-plugin-react/lib/util/propTypes.js:664:23
at Array.forEach ()
at DeclarePropTypesForTSTypeAnnotation.convertReturnTypeToPropTypes (/node_modules/eslint-plugin-react/lib/util/propTypes.js:653:34)
at DeclarePropTypesForTSTypeAnnotation.searchDeclarationByName (/node_modules/eslint-plugin-react/lib/util/propTypes.js:562:14)
at DeclarePropTypesForTSTypeAnnotation.visitTSNode (/node_modules/eslint-plugin-react/lib/util/propTypes.js:517:14)
at DeclarePropTypesForTSTypeAnnotation.traverseDeclaredInterfaceOrTypeAlias (/node_modules/eslint-plugin-react/lib/util/propTypes.js:610:14)
at Array.forEach ()




At propTypes.js it goes into the switch case for 'ObjectExpression' 

switch (res.type) {
case 'ObjectExpression':
iterateProperties(context, res.properties, (key, value, propNode) => {
const types = buildReactDeclarationTypes(value, key);
types.fullName = key;
types.name = key;
types.node = propNode;
types.isRequired = propsUtil.isRequiredPropType(value);
this.declaredPropTypes[key] = types;
});
break;
default:
}


with the following values:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ (index) โ”‚ 0 โ”‚ 1 โ”‚ 2 โ”‚ 3 โ”‚ 4 โ”‚ 5 โ”‚ id โ”‚ options โ”‚ report โ”‚ type โ”‚ argument โ”‚ range โ”‚ loc โ”‚ parent โ”‚ Values โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ context โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ 'react/display-name' โ”‚ [] โ”‚ [Function: report] โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚
โ”‚ resProperties โ”‚ [Object] โ”‚ [Object] โ”‚ [Object] โ”‚ [Object] โ”‚ [Object] โ”‚ [Object] โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚
โ”‚ key โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ undefined โ”‚
โ”‚ value โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ undefined โ”‚
โ”‚ propNode โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ 'SpreadElement' โ”‚ [Object] โ”‚ [ 13283, 13358 ] โ”‚ { start: [Object], end: [Object] } โ”‚ [Object] โ”‚ โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜


Which fails because the function isRequiredPropType fis called with `value` which is `undefined`
It seems to do with the TypeScript parsing in `convertReturnTypeToPropTypes(node)`

Now, one solution would be to simply change the isRequiredPropType function to return false when undefined is passed, like so:

function isRequiredPropType(propTypeExpression) {
return propTypeExpression && propTypeExpression.type === 'MemberExpression' && propTypeExpression.property.name === 'isRequired';
}
```

But I am not entirely sure if there is an underlying problem that caused this issue. From what I can tell this component somehow hit an edge case. The component in question is a function component which is wrapped in a Redux connect() to connect to the translations state.

If the above solution is acceptable I can create a pull request for it, but otherwise I would either need to find time to look into it, or let someone more familiar with the project find the solution :)

bug help wanted typescript

Most helpful comment

Sorry for this issue and thank you for your investigation!
I have made a pr #2802 .
Can you help me to test whether it works?
Thanks!

All 3 comments

What's the code being linted that causes this?

I've narrowed down the issue to the way the types for DispatchProps are being generated from the ReturnType of mapDispatchToProps.

We have a component as follows:

type ConnectedProps = DispatchProps &
  StateProps

const Component = ({ prop1, prop2, prop3 }: ConnectedProps) => {
  // Do stuff
  return (
    <StyledComponent>...</StyledComponent>
  )
}

const mapDispatchToProps = (dispatch: ThunkDispatch<State, null, Action>) => ({
  ...bindActionCreators(
    { prop1: importedAction, prop2: anotherImportedAction },
    dispatch,
  ),
})

const mapStateToProps = (state: State) => ({
  prop3: Selector.value(state),
})

type StateProps = ReturnType<typeof mapStateToProps>
type DispatchProps = ReturnType<typeof mapDispatchToProps>

If I comment out type DispatchProps = ReturnType<typeof mapDispatchToProps> or manually define it, the error disappears

Unfortunately I can't share the original code, as it is proprietary.

Sorry for this issue and thank you for your investigation!
I have made a pr #2802 .
Can you help me to test whether it works?
Thanks!

Was this page helpful?
0 / 5 - 0 ratings