【问题标题】:configuration with typescript jsx使用 typescript jsx 进行配置
【发布时间】:2021-11-12 19:10:06
【问题描述】:

我在使用 typescript 进行配置时遇到问题。这是我在 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"
  ]
}

这是我遇到的错误:

编译失败。

./src/Components/AdvancedSearch/AdvancedSearch.tsx 行 80:21: 'JSX' 未定义 no-undef

搜索关键字以了解有关每个错误的更多信息。

文件导致错误 AdvancedSearch.tsx:

在 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;

更新并添加了 AdvancedSearch 文件的导入:

import React from "react";
import MvwCheckbox from "../../Generic/MvCheckBox";
import "./AdvancedSearch.css";
import ContractType from "../../Interfaces/AdvanceSearchInterface"

【问题讨论】:

  • 谁能帮我解决这个错误?
  • 可以分享AdvancedSearch.tsx的完整代码吗?
  • @MajidM。刚刚在我的帖子中添加了完整的代码
  • 你的代码有import吗?
  • 是的,只是添加了几个导入

标签: javascript reactjs typescript eslint


【解决方案1】:

no-undef 在这种情况下导致 ESLint/TypeScript 兼容性问题。查看FAQ,其中特别提到了您的问题。我将在这里引用相关部分:

我们强烈建议您不要在 TypeScript 项目中使用 no-undef lint 规则。它提供的检查已经由 TypeScript 提供,无需配置 - TypeScript 只是在这方面做得更好。

从我们的 v4.0.0 版本开始,这也适用于类型。如果你使用来自 3rd 方包的全局类型(即来自 @types 包的任何东西),那么你必须适当地配置 ESLint 来定义这些全局类型。例如;来自 @types/reactJSX 命名空间是您必须在 ESLint 配置中定义的全局第 3 方类型。

请参阅此ESLint 指南以获取有关定义全局变量的帮助。您需要在您的.eslintrc 中添加一个globals 部分,其中包括JSX

"globals": {
    "JSX": "readonly",
},

您可以通过在您的.eslintrc 中定义rules 来完全关闭该项目的no-undef

"rules": {
    "no-undef": "off"
}

或者你可以添加一个overrides 部分来关闭打字稿文件的这个规则,特别是如果你有一个混合的 TS/JS 项目:

"overrides": [
    {
        "files": ["*.ts", "*.tsx"],
        "rules": {
            "no-undef": "off"
        }
    }
]

【讨论】:

  • 我在.eslint.json 中添加了所有内容,但仍然存在问题。还有其他解决方案吗?
  • .eslint.json 不是有效的配置文件 - 请确保其 .eslintrc.json。如果可能的话,在主帖中分享你所有的 ESLint 配置。
  • 它仍然没有解决我的错误
  • @NhanNguyen 我刚刚意识到这是一个基本的 ESLint 规则,实际上与 typescript-eslint 无关。请参阅我对第二个代码块的更新,然后再次尝试完全关闭该规则。如果这不起作用,那么我认为您的 ESLint 仍然为您的项目配置不正确。
【解决方案2】:

添加 JSX 属性

在 tsconfig.json 中添加这个属性

"jsx": "react-jsx"

【讨论】:

  • 我在.eslint.json 中添加了所有内容,但仍然存在问题。还有其他解决方案吗?
  • @NhanNguyen 抱歉,我的意思是在 tsconfig.json 中添加,请分享您的 ESLint 配置以更好地调试。
  • 在我还没有任何 ESLint 配置之前。
  • 但是当我添加"jsx": "react-jsx"时,我的终端说它必须是preservereactreact-native
猜你喜欢
  • 2016-07-11
  • 2021-10-30
  • 1970-01-01
  • 2016-03-05
  • 2020-02-04
  • 2016-09-10
  • 2016-09-17
  • 2022-11-09
  • 2010-10-10
相关资源
最近更新 更多