React 中休息道具的 TypeScript 解决方法 [英] TypeScript workaround for rest props in React

查看:42
本文介绍了React 中休息道具的 TypeScript 解决方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

TypeScript 2.1 现在支持对象传播/休息,因此不再需要解决方法!

TypeScript 2.1 now supports object spread/rest, so no workarounds are needed anymore!

TypeScript 支持在 React 中常用的 JSX 传播属性将 HTML 属性从组件传递到呈现的 HTML 元素:

TypeScript supports JSX spread attributes which is commonly used in React to pass HTML attributes from a component to a rendered HTML element:

interface LinkProps extends React.HTMLAttributes {
  textToDisplay: string;
}

class Link extends React.Component<LinkProps, {}> {
  public render():JSX.Element {
    return (
      <a {...this.props}>{this.props.textToDisplay}</a>
    );
  }
}

<Link textToDisplay="Search" href="http://google.com" />

然而,React 引入了一个 警告,如果你将任何未知的 props 传递给 HTML 元素.上面的例子会产生一个 React 运行时警告,指出 textToDisplay 的一个未知属性.对于像本例这样的案例,建议的解决方案是使用 object rest properties 来提取您的自定义 props 并将其余的用于 JSX 扩展属性:

However, React introduced a warning if you pass any unknown props to an HTML element. The above example would produce a React runtime warning that textToDisplay is an unknown prop of <a>. The suggested solution for a case like this example is to use object rest properties to extract out your custom props and use the rest for the JSX spread attributes:

const {textToDisplay, ...htmlProps} = this.props;
return (
  <a {...htmlProps}>{textToDisplay}</a>
);

但是 TypeScript 还不支持这种语法.我知道希望有一天我们将能够在 TypeScript 中做到这一点. (更新:TS 2.1 现在支持对象传播/休息!你为什么还在读这个??)同时有哪些解决方法?我正在寻找一种不会损害类型安全性并且发现它非常困难的解决方案.例如我可以这样做:

But TypeScript does not yet support this syntax. I know that hopefully some day we will be able to do this in TypeScript. (Update: TS 2.1 now supports object spread/rest! Why are you still reading this??) In the meantime what are some workarounds? I'm looking for a solution that doesn't compromise type-safety and finding it surprisingly difficult. For example I could do this:

const customProps = ["textDoDisplay", "otherCustomProp", "etc"];
const htmlProps:HTMLAttributes = Object.assign({}, this.props);
customProps.forEach(prop => delete htmlProps[prop]);

但这需要使用未根据实际道具验证的字符串属性名称,因此容易出现拼写错误和不良 IDE 支持.有没有更好的方法可以做到这一点?

But this requires the use of string property names that are not validated against the actual props and thus prone to typos and bad IDE support. Is there a better way we can do this?

推荐答案

您可能无法避免使用 this.props 的属性子集创建一个新对象,但您可以这样做具有类型安全性.

You probably can't avoid creating a new object with a subset of the properties of this.props, but you can do that with type safety.

例如:

interface LinkProps {
    textToDisplay: string;
}

const LinkPropsKeys: LinkProps = { textToDisplay: "" };

class Link extends React.Component<LinkProps & React.HTMLAttributes, {}> {
    public render(): JSX.Element {
        return (
            <a { ...this.getHtmlProps() }>{ this.props.textToDisplay }</a>
        );
    }

    private getHtmlProps(): React.HTMLAttributes {
        let htmlProps = {} as React.HTMLAttributes;

        for (let key in this.props) {
            if (!(LinkPropsKeys as any)[key]) {
                htmlProps[key] = this.props[key];
            }
        }

        return htmlProps;
    }
}

使用需要匹配 LinkPropsLinkPropsKeys 对象将帮助您保持接口和运行时查找之间的键同步.

Using LinkPropsKeys object, which needs to match the LinkProps, will help you keep the keys between the interface and the runtime lookup synchronized.

这篇关于React 中休息道具的 TypeScript 解决方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆