我应该使用啥 TypeScript 类型来引用我的道具中的匹配对象?

Posted

技术标签:

【中文标题】我应该使用啥 TypeScript 类型来引用我的道具中的匹配对象?【英文标题】:What TypeScript type should I use to reference the match object in my props?我应该使用什么 TypeScript 类型来引用我的道具中的匹配对象? 【发布时间】:2018-06-16 17:06:14 【问题描述】:

在我的 React 容器/组件中,我可以使用哪种类型来引用 React Router DOM 包含的 match 部分?

interface Props 
  match: any // <= What could I use here instead of any?


export class ProductContainer extends React.Component<Props> 
  // ...

【问题讨论】:

【参考方案1】:

这是我测试的完整示例。

DemoComponent.tsx

// Created by BaiJiFeiLong@gmail.com at 2021/9/25 20:15

import React from "react";
import RouteComponentProps from "react-router"

export default class DemoComponent extends React.Component<
    prop1: string,
    prop2: string,
    prop3: string
 & RouteComponentProps<
    param1: string,
    param2: string,
    param3: string
>, 
    state1: string,
    state2: string,
    state3: string
> 

    static defaultProps = 
        prop1: "PROP1",
        prop2: "PROP2",
        prop3: "PROP3"
    

    constructor(props: any) 
        super(props);
        this.state = 
            state1: "STATE1",
            state2: "STATE2",
            state3: "STATE3"
        
    


    render() 
        return <ul>
            <li>prop1 = this.props.prop1</li>
            <li>prop2 = this.props.prop2</li>
            <li>prop3 = this.props.prop3</li>
            <li>state1 = this.state.state1</li>
            <li>state2 = this.state.state2</li>
            <li>state3 = this.state.state3</li>
            <li>param1 = this.props.match.params.param1</li>
            <li>param2 = this.props.match.params.param2</li>
            <li>param3 = this.props.match.params.param3</li>
        </ul>
    

路线

<Route exact path="/demo/:param1/:param2/:param3" component=DemoComponent/>

来电

/demo/foo/bar/baz

结果

prop1 = PROP1
prop2 = PROP2
prop3 = PROP3
state1 = STATE1
state2 = STATE2
state3 = STATE3
param1 = foo
param2 = bar
param3 = baz

【讨论】:

【参考方案2】:

简单的解决方案

import  RouteComponentProps  from "react-router-dom";

const Container = ( match : RouteComponentProps< showId?: string>) => 
 const  showId  = match.params?.showId;//in case you need to take params

【讨论】:

【参考方案3】:

问题是即使在为match&lt;Params&gt; 创建了一个接口之后,类型警告仍然存在。这是对我有用的代码:

interface MatchParams 
    firstParam: string;
    optionalParam?: string;


export const CreditPortfolioDetail: FC<RouteComponentProps<MatchParams>> = (props) => 
    const  firstParam, optionalParam = props.match.params; 
    // ...

【讨论】:

什么是 FC ? FC> 它是 React.FC,它是 React.FunctionComponent 的类型别名。您的函数实际上是一个 FunctionComponent,通过明确说明,您还可以将 children 属性自动添加到您的道具中(类似于 RouteComponentProps 如何自动添加位置、匹配等)【参考方案4】:

您不需要显式添加它。你可以使用来自@types/react-routerRouteComponentProps&lt;P&gt; 作为道具的基本接口。 P 是匹配参数的类型。

import  RouteComponentProps  from 'react-router';

// example route
<Route path="/products/:name" component=ProductContainer />

interface MatchParams 
    name: string;


interface Props extends RouteComponentProps<MatchParams> 

// from typings
import * as H from "history";

export interface RouteComponentProps<P> 
  match: match<P>;
  location: H.Location;
  history: H.History;
  staticContext?: any;


export interface match<P> 
  params: P;
  isExact: boolean;
  path: string;
  url: string;

【讨论】:

这个问题是 Typescript 然后期望该组件的每次使用都实际传递到位置历史道具等中。RouteComponentProps 应该将这些道具作为可选的。必须用 Partial 包装。 @Glstunna 感谢您让我意识到,如果使用部分功能会怎样?以及 OP:请包括您的导入。 TypeScript 一直要求我将整个道具集传递给组件(`,我也有代码如上所示。 @LeonardoViada 尝试使用&lt;Route component=MyComp /&gt;传递组件【参考方案5】:

要添加到上面@Nazar554 的答案,RouteComponentProps 类型应从react-router-dom 导入,并按如下方式实现。

import BrowserRouter as Router, Route, RouteComponentProps  from 'react-router-dom';

interface MatchParams 
    name: string;


interface MatchProps extends RouteComponentProps<MatchParams> 

此外,为了允许可重复使用的组件,render() 函数允许您仅传递组件需要的内容,而不是整个 RouteComponentProps

<Route path="/products/:name" render=( match: MatchProps) => (
    <ProductContainer name=match.params.name /> ) />

// Now Product container takes a `string`, rather than a `MatchProps`
// This allows us to use ProductContainer elsewhere, in a non-router setting!
const ProductContainer = ( name: string ) => 
     return (<h1>Product Container Named: name</h1>)

【讨论】:

太棒了!不错的补充

以上是关于我应该使用啥 TypeScript 类型来引用我的道具中的匹配对象?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Typescript 在 React 中定义 <video> 引用的类型?

TypeScript 中是不是有在类中使用的关键字来获取其类型?

我应该将啥类型添加到作为参数接收的类构造函数中?

我应该使用啥类型的数据结构来保存表行?

ReactJS 和 Typescript :引用一个值,但在此处用作类型 (TS2749)

Java 中应该使用啥数据类型来代表价格