gpt4 book ai didi

typescript - React 路由渲染属性类型挑战 typescript

转载 作者:行者123 更新时间:2023-12-05 02:44:42 25 4
gpt4 key购买 nike

我有一些名为 project 的组件 Prop 通过了 LinkRoute像这样(我的项目对象进入 state 扩展属性):

<Link
to={{
pathname: path,
state: {
project,
},
}}
key={project.id}
>
<ProjectSummary project={project} deleteCallback={projectDelete}/>
</Link>

然后它在路由中接收并可以像这样传递给链接的组件:

<Route
path='/project/:id'
render={({ location }:any) => { //TYPE CHALLENGE HERE
const { state } = location;
return <ProjectDetails project={state.project} />
}}
/>

找到 any输入 //TYPE CHALLENGE HERE评论。我尝试了很多类型的“react-router”和“react-router-dom”,但找不到匹配的类型。

最接近的似乎是这个:

export interface RouteComponentProps<
Params extends { [K in keyof Params]?: string } = {},
C extends StaticContext = StaticContext,
S = H.LocationState
> {
history: H.History<S>;
location: H.Location<S>;
match: match<Params>;
staticContext?: C;
}

由于组件从该接口(interface)接收所有路由参数,但我扩展了 location传入我的项目对象的位置。如果有任何相关性,这是 project 的类型我传入的对象:

export interface IFirebaseProject {
id: string,
authorFirstName: string,
authorId: string,
authorLastName: string
content: string
createdAt: firebase.firestore.Timestamp //firebase timestamp
title: string
}

我还发布了我认为最接近的方法时遇到的错误:

render={({ location }:RouteComponentProps<any, StaticContext, IFirebaseProject>) => {}
No overload matches this call.
Overload 1 of 2, '(props: RouteProps | Readonly<RouteProps>): Route<RouteProps>', gave the following error.
Type '({ location }: RouteComponentProps<any, StaticContext, IFirebaseProject>) => JSX.Element' is not assignable to type '(props: RouteComponentProps<any, StaticContext, unknown>) => ReactNode'.
Types of parameters '__0' and 'props' are incompatible.
Type 'RouteComponentProps<any, StaticContext, unknown>' is not assignable to type 'RouteComponentProps<any, StaticContext, IFirebaseProject>'.
Type 'unknown' is not assignable to type 'IFirebaseProject'.
Overload 2 of 2, '(props: RouteProps, context: any): Route<RouteProps>', gave the following error.
Type '({ location }: RouteComponentProps<any, StaticContext, IFirebaseProject>) => JSX.Element' is not assignable to type '(props: RouteComponentProps<any, StaticContext, unknown>) => ReactNode'.ts(2769)
index.d.ts(89, 5): The expected type comes from property 'render' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<Route<RouteProps>> & Readonly<RouteProps> & Readonly<...>'
index.d.ts(89, 5): The expected type comes from property 'render' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<Route<RouteProps>> & Readonly<RouteProps> & Readonly<...>'

编辑:

更新了 render 中日志错误的屏幕截图: enter image description here

错误的文本全文 render={({ location }: { location: Location<{ project: IFirebaseProject }> }) => {尝试:

No overload matches this call.
Overload 1 of 2, '(props: RouteProps | Readonly<RouteProps>): Route<RouteProps>', gave the following error.
Type '({ location }: { location: Location<{ project: IFirebaseProject;}>; }) => JSX.Element' is not assignable to type '(props: RouteComponentProps<any, StaticContext, unknown>) => ReactNode'.
Types of parameters '__0' and 'props' are incompatible.
Type 'RouteComponentProps<any, StaticContext, unknown>' is not assignable to type '{ location: Location<{ project: IFirebaseProject; }>; }'.
Types of property 'location' are incompatible.
Type 'Location<unknown>' is not assignable to type 'Location<{ project: IFirebaseProject; }>'.
Type 'unknown' is not assignable to type '{ project: IFirebaseProject; }'.
Overload 2 of 2, '(props: RouteProps, context: any): Route<RouteProps>', gave the following error.
Type '({ location }: { location: Location<{ project: IFirebaseProject;}>; }) => JSX.Element' is not assignable to type '(props: RouteComponentProps<any, StaticContext, unknown>) => ReactNode'.ts(2769)
index.d.ts(89, 5): The expected type comes from property 'render' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<Route<RouteProps>> & Readonly<RouteProps> & Readonly<...>'
index.d.ts(89, 5): The expected type comes from property 'render' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<Route<RouteProps>> & Readonly<RouteProps> & Readonly<...>'

最佳答案

RouteComponentProps

你们太亲密了! S RouteComponentProps 的参数控制 statelocation 键入和 history props,这样就是你想要使用的东西。

错误是你设置了SIFirebaseProject这意味着状态本身就是一个 IFirebaseProject .但实际上状态看起来像{project} .它是一个带有键 project 的对象其值为 IFirebaseProject .所以 S 的正确类型是{project: IFirebaseProject} .

正确设置所有类型后,它是这样的:

render={({ location }: RouteComponentProps<{id: string}, StaticContext, {project: IFirebaseProject}>)  => {

但是location不使用其他两个泛型,所以这很好:

render={({ location }: RouteComponentProps<any, any, {project: IFirebaseProject}>)  => {

地点

就我个人而言,我只想为 location 声明一个类型属性,因为这是 RouteComponentProps 的唯一属性你真正需要的。我不喜欢使用依赖于未使用的泛型的类型。

标的Location type 来自 history 包,它是 react-router 的依赖项。它的类型通过 import * as H from "history" 导入到 react-router-dom 类型中,所以这就是你看到 H.Location 的原因.但是你可以直接导入它:

import {Location} from "history";

然后像这样使用它:

render={({ location }: {location: Location<{project: IFirebaseProject}>})  => {

Typescript Playground Link

编辑:rendercomponent

您的 CodeSandbox 中发生了一些奇怪的事情,因为我确实看到了错误,但我无法在 TS Playground 中单独重现它。与其用头撞墙,不如使用稍微不同的方法来规避错误。

component prop 的类型比 render 更宽松因为它允许 Prop 类型为 RouteComponentProps<any> (我们期望的)或 any (字面意思是任何东西)。只需将 Prop 名称从 render 切换至 component让它突然工作!我们不想定义内联组件,因为它将是 recreated on each render , 但我们可以在外部定义它。

我们现在将使用 component Route 的 Prop 而不是使用 render功能:

<Route path="/project/:id" component={ProjectScreen} />

有两个选项可以访问 ProjectScreen 中的位置这两者似乎都对我有用。

  1. 我们可以通过组件中注入(inject)的 Prop 来访问它。这正是我们之前所拥有的,但在 component 上是允许的而不是 render由于 any在 Prop 上打字。
const ProjectScreen = ({ location }: { location: Location<{ project: IFirebaseProject }>; }) => {
const { state } = location;
return <ProjectDetails project={state.project} />;
};
  1. 我们可以使用 useLocation 通过路由器上下文访问它钩。这个钩子(Hook)是依赖于状态的泛型,所以我们可以在调用它的时候指定状态类型。我们定义了一个组件,它不接受任何 Prop 但呈现适当的 ProjectDetails。基于钩子(Hook)的位置。
const ProjectScreen = () => {
const { state } = useLocation<{ project: IFirebaseProject }>();
return <ProjectDetails project={state.project} />;
}

关于typescript - React 路由渲染属性类型挑战 typescript ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66309218/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com