React/TypeScript:扩展具有其他属性的组件

Ema*_*rco 18 typescript reactjs

我正在尝试使用react来重新创建我的current组件(用纯打字稿编写),但我找不到一种方法来为扩展另一个的组件提供额外的道具.

export interface DataTableProps {
    columns: any[];
    data: any[];
}

export class DataTable extends React.Component<DataTableProps, {}> {
   render() {
       // -- I can use this.props.columns and this.props.data --
   }
}

export class AnimalTable extends DataTable {
    render() {
       // -- I would need to use a this.props.onClickFunction -- 
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是我需要给AnimalTable一些与DataTable无关的道具.我怎样才能做到这一点 ?

Nit*_*mer 41

你需要制作DataTable通用的,这样你才能使用扩展的接口DataTableProps:

export interface AnimalTableProps extends DataTableProps {
    onClickFunction: Function;
}

export class DataTable<T extends DataTableProps> extends React.Component<T, {}> { }

export class AnimalTable extends DataTable<AnimalTableProps> {
    render() {
        // this.props.onClickFunction should be available
    }
}
Run Code Online (Sandbox Code Playgroud)


iro*_*nic 9

根据经验,最好避免继承。幸运的是,TS 和 React 都是很棒的工具,可以实现这一点(例如,与 C# 不同,继承通常可以为您节省大量样板文件)

export interface DataTableProps {
    columns: any[];
    data: any[];
}

export class DataTable extends React.Component<DataTableProps, {}> {
   render() {
       // -- I can use this.props.columns and this.props.data --
   }
}

export type AnimalTableProps = DataTableProps & {
    onClickFunction: () => void;
};

export class AnimalTable extends React.Component<AnimalTableProps, {}> {
    render() {
        const {onClickFunction, ...tableProps} = this.props;
        // use onClickFunction however you need it
        return <DataTable {...tableProps}></DataTable>
    }
}
Run Code Online (Sandbox Code Playgroud)


rad*_*erg 6

我发现的最优雅的解决方案(没有额外的泛型类)是

interface IBaseProps {
    name: string;
}

class Base<P> extends React.Component<P & IBaseProps, {}>{

}

interface IChildProps extends IBaseProps {
    id: number;
}

class Child extends Base<IChildProps> {
    render(): JSX.Element {
        return (
            <div>
                {this.props.id}
                {this.props.name} 
            </div>
        );
    }
}
Run Code Online (Sandbox Code Playgroud)


Ant*_*ris 5

对于那些需要的人,基类可以声明所有实例必须实现的必需/​​抽象方法:

import { Component } from 'react'


abstract class TestComponent<P = {}, S = {}, SS = any> extends Component<P, S, SS> {
  abstract test(): string
}


type Props = {
  first: string,
  last: string,
}

type State = {
  fullName: string,
}

class MyTest extends TestComponent<Props, State> {
  constructor(props: Props) {
    super(props)
    this.state = {
      fullName: `${props.first} ${props.last}`
    }
  }

  test() {
    const { fullName } = this.state
    return fullName
  }
}

Run Code Online (Sandbox Code Playgroud)