Currently starting up the server on my client side, the error above is what I have been
getting. I am using TypeScript, ReactJS, ESLint. I can’t seem to go forward since this error
has been haunting me. The GitHub page for ESLint hasn’t been of much help either.
This error went up after I had created the useMutation component and exported it in index.ts
.
Not sure how to get rid of this error.
Below is my package.json
{
"name": "tinyhouse_client",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"@types/jest": "^24.0.0",
"@types/node": "^12.0.0",
"@types/react": "^16.9.35",
"@types/react-dom": "^16.9.0",
"@typescript-eslint/parser": "^3.0.2",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-scripts": "3.4.1",
"typescript": "~2.23.0"
},
"resolutions": {
"@typescript-eslint/eslint-plugin": "^2.23.0",
"@typescript-eslint/parser": "^2.23.0",
"@typescript-eslint/typescript-estree": "^2.23.0"
},
"scripts": {
"start": "react-scripts start",
" build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
**strong text** "proxy": "http://localhost:9000"
}
Below is my index.ts
export * from './server';
export * from './useQuery';
export * from './useMutation';
And my useMutation.ts
import { useState } from 'react';
import { server } from './server';
interface State<TData> {
data: TData | null;
loading: boolean;
error: boolean;
}
type MutationTuple<TData, TVariables> = [
(variables?: TVariables | undefined) => Promise<void>,
State<TData>
];
export const useMutation = <TData = any, TVariables = any>(
query: string
): MutationTuple<TData, TVariables> => {
const [state, setState] = useState<State<TData>>({
data: null,
loading: false,
error: false,
})
const fetch = async (variables?: TVariables) => {
try {
setState({ data: null, loading: true, error: false });
const { data, errors } = await server.fetch<TData, TVariables>({ query, variables });
if (errors && errors.length) {
throw new Error(errors[0].message);
}
setState({ data, loading: false, error: false });
} catch (err) {
setState({ data: null, loading: false, error: true });
throw console.error(err);
}
}
return [fetch, state];
};
I considered giving a comment under the answer by taggon to this very question, but well, i felt it owed more explanation for those interested in details.
Uncaught TypeError: Cannot read property ‘value’ of undefined is strictly a JavaScript error.
(Note that value can be anything, but for this question value is ‘map’)
It’s critical to understand that point, just so you avoid endless debugging cycles.
This error is common especially if just starting out in JavaScript (and it’s libraries/frameworks).
For React
, this has a lot to do with understanding the component lifecycle methods.
// Follow this example to get the context
// Ignore any complexity, focus on how 'props' are passed down to children
import React, { useEffect } from 'react'
// Main component
const ShowList = () => {
// Similar to componentDidMount and componentDidUpdate
useEffect(() => {// dispatch call to fetch items, populate the redux-store})
return <div><MyItems items={movies} /></div>
}
// other component
const MyItems = props =>
<ul>
{props.items.map((item, i) => <li key={i}>item</li>)}
</ul>
/**
The above code should work fine, except for one problem.
When compiling <ShowList/>,
React-DOM renders <MyItems> before useEffect (or componentDid...) is called.
And since `items={movies}`, 'props.items' is 'undefined' at that point.
Thus the error message 'Cannot read property map of undefined'
*/
As a way to tackle this problem, @taggon gave a solution (see first anwser or link).
Solution: Set an initial/default value.
In our example, we can avoiditems
being ‘undefined’ by declaring adefault
value of an empty array.Why? This allows React-DOM to render an empty list initially.
And when theuseEffect
orcomponentDid...
method is executed, the component is re-rendered with a populated list of items.
// Let's update our 'other' component
// destructure the `items` and initialize it as an array
const MyItems = ({items = []}) =>
<ul>
{items.map((item, i) => <li key={i}>item</li>)}
</ul>
- I have tried restarting my IDE and the issue persists.
- I have updated to the latest version of the packages.
- I have read the FAQ and my problem is not listed.
Repro
// some export in a file1.ts, it doesn't matter what you export export type Foo = number // file2.ts, import from file1.ts and have an array return type on a function. // The [sometype] return type seems to be the key to causing the issue. import { Foo } from './test-import' // This line has error: "Parsing error: Cannot read property 'map' of undefined" export function foo(id: Foo): [number] { // The [number] or any array return type seems to be the cause return [id] }
Expected Result
I expected it not to fail.
Actual Result
Parsing error: Cannot read property ‘map’ of undefined
What version of our tooling are you using?
That section is part of our template for a reason.
As mentioned in the first comment in the template:
<!--
Please don't ignore this template.
If you ignore it, we're just going to respond asking you to fill it out, which wastes everyone's time.
The more relevant information you can include, the faster we can find the issue and fix it without asking you for more info.
-->
«@typescript-eslint/eslint-plugin»: «4.0.0»,
«@typescript-eslint/parser»: «4.0.0»,
«eslint»: «7.7.0»,
«typescript»: «4.0.2»,
TS4.0 included a breaking change to their AST shape which we’ve properly handled since our v3.3.0
release.
If you’ve got v4 of our packages installed and you’re still seeing errors, likely you also have older version(s) of our tooling installed alongside the new versions, and your local tooling is using the older versions.
See discussion in: #2260
Packages like react-scripts
(part of create react app) will depend on their own (older) versions of our packages. You will have to use resolutions to bypass.
Yes. Confirmed that we did have an older version of the parser being pulled in by another package. Terribly sorry about this. Working fine now.
github-actions
bot
locked as resolved and limited conversation to collaborators
Oct 12, 2020
Edit: as noted by Meng-Yuan Huang, this issue no longer occurs in [email protected]^4.0.1
This error occurs because react-scripts
has a direct dependency on the 2.xx range of @typescript-eslint/parser
and @typescript-eslint/eslint-plugin
.
You can fix this by adding a resolutions field to your package.json
as follows:
"resolutions": {
"**/@typescript-eslint/eslint-plugin": "^4.1.1",
"**/@typescript-eslint/parser": "^4.1.1"
}
NPM users: add the resolutions field above to your package.json
but use npx npm-force-resolutions to update package versions in package-lock.json
.
Yarn users: you don’t need to do anything else. See selective dependency resolutions for more info.
NOTE: if you’re using a monorepo/Yarn workspaces, the resolutions
field must be in the top-level package.json
.
NOTE: yarn add
and yarn upgrade-interactive
don’t respect the resolutions
field and they can generate a yarn.lock
file with incorrect versions as a result. Watch out.
Your version of TypeScript is not compatible with your eslint. You can fix it by upgrading these two dependencies to the latest version.
TypeScript 4.0.5 is compatible with version 4.6.0
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^4.6.0",
"@typescript-eslint/parser": "^4.6.0",
}
TypeScript 4.1.5 is compatible with version 4.18.0
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^4.18.0",
"@typescript-eslint/parser": "^4.18.0",
}
TypeScript 4.2.4 is compatible with version 4.23.0
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^4.23.0",
"@typescript-eslint/parser": "^4.23.0",
}
TypeScript 4.3.2 is compatible with version 4.25.0
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^4.25.0",
"@typescript-eslint/parser": "^4.25.0",
}
TypeScript 4.5.5 is compatible with version 5.10.2
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.10.2",
"@typescript-eslint/parser": "^5.10.2",
}
TypeScript 4.6.2 is compatible with version 5.15.0
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.15.0",
"@typescript-eslint/parser": "^5.15.0",
}
TypeScript 4.7.2 is compatible with version 5.26.0
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.26.0",
"@typescript-eslint/parser": "^5.26.0",
}
Currently starting up the server on my client side, the error above is what I have been
getting. I am using Typescript, React, ESlint. I can’t seem to go forward since this error
has been haunting me. The github page for Eslint hasn’t been much help either.
This error went up after I had created the useMutation component and exported it in the
index.ts,
Not sure how to get rid of this error.
Below is my package.json
{
"name": "tinyhouse_client",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"@types/jest": "^24.0.0",
"@types/node": "^12.0.0",
"@types/react": "^16.9.35",
"@types/react-dom": "^16.9.0",
"@typescript-eslint/parser": "^3.0.2",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-scripts": "3.4.1",
"typescript": "~2.23.0"
},
"resolutions": {
"@typescript-eslint/eslint-plugin": "^2.23.0",
"@typescript-eslint/parser": "^2.23.0",
"@typescript-eslint/typescript-estree": "^2.23.0"
},
"scripts": {
"start": "react-scripts start",
" build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
**strong text** "proxy": "http://localhost:9000"
}
Below is my index.ts
export * from './server';
export * from './useQuery';
export * from './useMutation';
And my useMutation.ts
import { useState } from 'react';
import { server } from './server';
interface State<TData> {
data: TData | null;
loading: boolean;
error: boolean;
}
type MutationTuple<TData, TVariables> = [
(variables?: TVariables | undefined) => Promise<void>,
State<TData>
];
export const useMutation = <TData = any, TVariables = any>(
query: string
): MutationTuple<TData, TVariables> => {
const [state, setState] = useState<State<TData>>({
data: null,
loading: false,
error: false,
})
const fetch = async (variables?: TVariables) => {
try {
setState({ data: null, loading: true, error: false });
const { data, errors } = await server.fetch<TData, TVariables>({ query, variables });
if (errors && errors.length) {
throw new Error(errors[0].message);
}
setState({ data, loading: false, error: false });
} catch (err) {
setState({ data: null, loading: false, error: true });
throw console.error(err);
}
}
return [fetch, state];
};