我如何正确使用带有 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
中的 BrowseMain
和 UploadMain
路由上抛出以下错误:
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/
我正在尝试在使用 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
中的 BrowseMain
和 UploadMain
路由上抛出以下错误:
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/