【问题标题】:How to wrap a component and inherit its props interface如何包装组件并继承其 props 接口
【发布时间】:2018-05-02 18:19:55
【问题描述】:

我想扩展一个 Button 组件并扩展它的 props 接口类型,以便接受和传递普通 Button 具有的所有 props。在下面的示例中,我创建了一个按钮,该按钮从它的 onClick 函数接收一个承诺,并在等待它解析时显示加载器。

我的问题似乎是编译器不知道在哪里可以找到 ButtonProps,它可能是在自己的命名空间中定义的。

我能以某种方式采用该定义并将其扩展为我自己的组件吗?我不想重新定义像“类型”这样的道具,只是通过它们。

import React from 'react';
import { Button } from 'antd';

// extend interface already defined in antd
interface ButtonProps {
  onClick: (event: any) => Promise<any>;
}

interface AsyncButtonState {
  loading: boolean;
}

export class AsyncButton extends React.Component<
  ButtonProps,
  AsyncButtonState
> {
  public state = {
    loading: false,
  };

  public render() {
    return (
      <Button
        {...this.props}
        onClick={this.handleClick}
        loading={this.state.loading}
      />
    );
  }

  private handleClick = async evt => {
    this.setState({ loading: true });
    await this.props.onClick(evt);
    this.setState({ loading: false });
  };
}

export default AsyncButton;

---- 编辑----

我找到了一种从antd导入ButtonProps接口的方法。现在我只需要弄清楚我认为如何扩展它。

import { ButtonProps } from 'antd/lib/button';

interface ButtonProps {
  onClick: (event: any) => Promise<any>;
  children: React.ReactNode;
}

这会导致导入错误:“导入声明与 ButtonProps 的本地声明冲突”

----- 再次编辑----

我曾经解决过这个问题

import { Button } from 'antd';
import { ButtonProps } from 'antd/lib/button';

interface AsyncButtonState {
  loading: boolean;
}

interface AsyncButtonProps extends ButtonProps {
  onClick: (event: any) => Promise<any>;
  foo?: string;
}

...但现在看来 ButtonProps 不再作为接口导出,而是作为类型导出。现在呢?

【问题讨论】:

    标签: typescript antd


    【解决方案1】:

    现在 Antd 的 props 被导出为 type 这似乎是解决它的方法:

    import { Button } from 'antd';
    import { ButtonProps } from 'antd/lib/button';
    
    interface AsyncButtonProps {
      onClick: (event: any) => Promise<any>;
      foo?: string;
    }
    
    export class AsyncButton extends React.Component<
      AsyncButtonProps & ButtonProps,
      AsyncButtonState
    > {
      public render() {
        return (
          <Button
            {...this.props}
            onClick={this.handleClick}
            loading={this.state.loading}
          />
        );
      }
    }
    

    【讨论】:

      【解决方案2】:

      毕竟这很容易。

      import { Button } from 'antd';
      import { ButtonProps } from 'antd/lib/button';
      
      interface AsyncButtonState {
        loading: boolean;
      }
      
      interface AsyncButtonProps extends ButtonProps {
        onClick: (event: any) => Promise<any>;
        foo?: string;
      }
      

      返回 promise 的 onClick 处理程序已经与当前的 ButtonProps 接口兼容,所以我认为这对我来说不是必需的。但这显示了添加另一个名为 foo 的可选道具。

      【讨论】:

      • ButtonProps 现在导出为类型而不是接口了?现在有人知道如何解决这个问题吗?
      【解决方案3】:

      我不熟悉打字稿,这行得通吗?

      interface ButtonProps {
        onClick: (event: any) => Promise<any>;
        ...Button.propTypes
      }
      

      我们用 es6 做类似的事情并且效果很好

      const propTypes = {
         something: PropTypes.string,
         ...Button.propTypes
      }
      
      MyButton.propTypes = propTypes;
      

      【讨论】:

      • 是的,Typescript 应该可以实现类似的功能。我认为接口只是合并(你不需要传播)。我找到了一种导入按钮道具接口供我自己使用的方法(见编辑),只是我不知道如何让编译器明白我正在从 antd 包中寻址一个接口,而不是创建一个新接口。也许这是related
      猜你喜欢
      • 2015-07-05
      • 1970-01-01
      • 2015-07-05
      • 2015-11-12
      • 2020-03-20
      • 2016-01-05
      • 1970-01-01
      • 2021-04-10
      相关资源
      最近更新 更多