我如何正确使用带有 TypeScript 和 ESLint 的 ReactJS Reach Router?

How do I correctly use ReactJS Reach Router with TypeScript & ESLint?

我正在尝试在使用 TypeScript 和 ESLint 的项目中使用 Reach Router 实现仅限客户端的路由。这是我的初始实现:

// src/pages/app/[...].tsx
import { Router, Redirect, useLocation } from '@reach/router';
import * as React from 'react';

import BrowseMain from '../../components/BrowseMain';
import Layout from '../../components/Layout';
import UploadMain from '../../components/UploadMain';
import * as styles from '../../styles/[...].module.scss';

const IndexPage = () => {
  const currLocation = useLocation();

  return (
    <Layout>
      <main className={styles.indexMain}>
        <Router basepath="/app">
          {['/', '/browse', '/browse/'].map((path) => <BrowseMain key={path} path={path} />)}
          {['/upload', '/upload/'].map((path) => <UploadMain key={path} path={path} />)}
          {/* Redirect 404 */}
          <Redirect noThrow default from={currLocation.pathname} to="/" />
        </Router>
      </main>
    </Layout>
  );
};

export default IndexPage;

// src/components/BrowseMain.tsx
import * as React from 'react';

import '../styles/BrowseMain.module.scss';
import Main from './Main';

const BrowseMain = () => <Main>Browse</Main>;

export default BrowseMain;

// UploadMain is similar to BrowseMain, so they are facing the same issue here.

// src/components/Main.tsx
import * as React from 'react';

import '../styles/Main.module.scss';

type MainProps = {
  children: string,
};

const Main = ({ children }: MainProps) => <>{children}</>;

export default Main;

此时,TypeScript 在 [...].tsx 中的 BrowseMainUploadMain 路由上抛出以下错误:

TS2322: Type '{ key: string; path: string; }' is not assignable to type 'IntrinsicAttributes'.   Property 'path' does not exist on type 'IntrinsicAttributes'.

根据 Reach Router 的 Usage with TypeScript 文档,我做了以下更改:

import { RouteComponentProps } from '@reach/router';
import * as React from 'react';

import '../styles/BrowseMain.module.scss';
import Main from './Main';

const BrowseMain = (props: RouteComponentProps) => <Main>Browse</Main>;

export default BrowseMain;

这解决了之前的 linting 错误,但是又引发了两个新错误:

TS6133: 'props' is declared but its value is never read.

ESLint: 'props' is defined but never used.(@typescript-eslint/no-unused-vars)

此时,我卡住了。我尝试了两种不同的方法,但它们都引发了 linting 错误:

// ESLint: Unexpected empty object pattern.(no-empty-pattern)
const BrowseMain = ({}: RouteComponentProps) => (

// ESLint: '_' is defined but never used.(@typescript-eslint/no-unused-vars)
const BrowseMain = (_: RouteComponentProps) => (

我觉得我现在处在一个该死的情况下,如果你这样做,如果你不这样做,那该死的。为不会使用的道具声明显式类型的正确方法是什么?

您可以使用泛型指定道具。在您的情况下,它看起来像:

const BrowserMain: React.FC<RouteComponentProps> = () => <Main>Browse</Main

但是使用 React.FC 是 discouraged 所以你也可以使用 typescript 调用签名

type BrowserMainFC = {
  (props: RouteComponentProps): JSX.Element
}

const BrowseMain: BrowserMainFC = () => <div />

查看此资源:https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/function_components/