'ESLint configuration with typescript jsx
I am having issues with configuration with typescript. Here is my following code in tsconfig.json:
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve"
},
"include": [
"src"
]
}
and here is the error that i am having:
Failed to compile.
./src/Components/AdvancedSearch/AdvancedSearch.tsx Line 80:21: 'JSX' is not defined no-undef
Search for the keywords to learn more about each error.
file causing error AdvancedSearch.tsx:
edit and update full code in AdvancedSearch
type AdvancedSearchState = {
containerHeight: number,
showMore: boolean,
transitioning: boolean;
};
type Props = {
show: boolean;
// selected: [ContractType];
selected: any;
onChange: (e: any) => void;
contracts: ContractType[];
};
class AdvancedSearch extends React.Component<Props, AdvancedSearchState> {
advancedSearchContainer: React.RefObject<HTMLDivElement>;
advancedSearchWrapper: React.RefObject<HTMLDivElement>;
width: number = 3;
labelStyle = {
color: "#1e7e34",
"text-decoration": "underline"
};
constructor(props: Props) {
super(props);
this.selectItem = this.selectItem.bind(this);
this.advancedSearchContainer = React.createRef();
this.advancedSearchWrapper = React.createRef();
this.resize = this.resize.bind(this);
this.state = {
showMore: false,
containerHeight: 0,
transitioning: true
};
}
getContainerHeight() {
let containerHeight = 0;
if (this.advancedSearchContainer.current) {
containerHeight = this.advancedSearchContainer.current.clientHeight;
}
return containerHeight;
}
resize() {
let containerHeight = this.getContainerHeight();
if (this.state.containerHeight !== containerHeight) {
this.setState({ containerHeight: containerHeight });
}
}
componentDidMount() {
this.setState({ containerHeight: this.getContainerHeight() });
window.addEventListener("resize", this.resize);
}
componentWillUnmount() {
window.removeEventListener("resize", this.resize);
}
componentDidUpdate() {
console.log(this.state.containerHeight);
this.resize();
}
selectItem(name: string) {
// let selectedContract = name.currentTarget.name;
// currently change the selectedContract as just the string
let selectedContract = name;
let selected = this.props.selected;
let inx = this.props.selected.indexOf(selectedContract);
if (inx > -1) {
selected.splice(inx, 1);
} else {
selected.push(selectedContract);
}
let event = {
target: {
value: selected,
name: "contracts"
}
};
this.props.onChange(event);
}
chunkArray(array: JSX.Element[], width: number) {
return array.reduce((acc: any[][], item: any, index: number) => {
let loc = Math.floor(index / width);
if (!acc[loc]) {
acc[loc] = [];
}
acc[loc].push(item);
return acc;
}, []);
}
render() {
//TODO: Should be passed in and not the list of contracts
let initialList = this.chunkArray(
this.props.contracts.map(contractType => {
return (
<div className="four columns contract-container">
<span className="contract-header">
{contractType.contractTypeName}
</span>
<dl className="contract-list">
{contractType.contracts.map(contract => {
return (
<li className="contract">
<MvwCheckbox
labelStyle={this.labelStyle}
onChange={this.selectItem}
checked={this.props.selected.indexOf(contract.name) >= 0}
label={contract.name}
name={contract.name}
/>
</li>
);
})}
</dl>
</div>
);
}),
this.width
);
let list;
if (this.state.showMore) {
list = initialList.map((item: React.ReactNode) => {
return <div className="row">{item}</div>;
});
} else {
list = [initialList[0]].map(item => {
return <div className="row">{item}</div>;
});
}
return (
<div
className={
"twelve column advanced-search " + (this.props.show ? "show" : "")
}
>
<div
className="advanced-search-wrapper"
ref={this.advancedSearchWrapper}
style={{ height: this.props.show ? this.state.containerHeight : 0 }}
>
<div
className="advanced-search-content"
ref={this.advancedSearchContainer}
>
<div className="advanced-search-body">
<div className="advanced-search-title">
<p>
Please select the product(s) you wish to use for your
Reservation Search:
</p>
</div>
<div className="advanced-search-list">{list}</div>
</div>
</div>
</div>
</div>
);
}
}
export default AdvancedSearch;
Updated and added import for AdvancedSearch file:
import React from "react";
import MvwCheckbox from "../../Generic/MvCheckBox";
import "./AdvancedSearch.css";
import ContractType from "../../Interfaces/AdvanceSearchInterface"
Solution 1:[1]
no-undef
is causing an ESLint/TypeScript compatibility problem in this instance. Check out the FAQ which mentions your issue specifically. I will just quote the relevant parts here:
We strongly recommend that you do not use the
no-undef
lint rule on TypeScript projects. The checks it provides are already provided by TypeScript without the need for configuration - TypeScript just does this significantly better.As of our v4.0.0 release, this also applies to types. If you use global types from a 3rd party package (i.e. anything from an
@types
package), then you will have to configure ESLint appropriately to define these global types. For example; theJSX
namespace from@types/react
is a global 3rd party type that you must define in your ESLint config.
See this ESLint guide for help on defining globals. You will need to add a globals
section to your .eslintrc
which includes JSX
:
"globals": {
"JSX": "readonly",
},
You can turn no-undef
off for the project altogether by defining rules
in your .eslintrc
:
"rules": {
"no-undef": "off"
}
Or you can add an overrides
section to turn off this rule for typescript files specifically if you have a mixed TS/JS project:
"overrides": [
{
"files": ["*.ts", "*.tsx"],
"rules": {
"no-undef": "off"
}
}
]
Solution 2:[2]
Add JSX property
Add this property in tsconfig.json
"jsx": "react-jsx"
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 |