如何将 React.cloneElement 与 TypeScript 结合使用?

Mar*_*cky 8 typescript reactjs

我有呈现选项卡内容的组件。它只是检测孩子是否是唯一的孩子,如果不是,则将它们包装在 div 中。它还可以(可选)通过克隆子项来应用具有样式的道具。我几个月前编写了这个组件,然后更新了一些库和 TypeScript。今天我查看它的代码,发现错误。

组件

import * as React from 'react';

export interface PageTabContentShape {
  title: string;
  pageTabName?: string;
  withContainer?: boolean;
  containerStyle?: React.CSSProperties;
  labelTestid?: string;
  children: React.ReactElement;
}

export const PageTabContent: React.ComponentType<PageTabContentShape> = (props) => {
  let child = React.Children.only(props.children);
  if (props.withContainer) {
    return (
      <div style={props.containerStyle}>
        {child}
      </div>
    );
  }
  // pass styles to only child when there is no wrapper
  if (props.containerStyle && React.isValidElement<{ containerStyle }>(child)) {
    child = React.cloneElement(child, { containerStyle: props.containerStyle });
  }
  if (null != child) {
    return child;
  }
  return null;
};
Run Code Online (Sandbox Code Playgroud)

错误:

Argument type ReactElement<{containerStyle}> is not assignable to parameter
type DetailedReactHTMLElement<HTMLAttributes<HTMLElement>, HTMLElement> 
Run Code Online (Sandbox Code Playgroud)

Argument type {containerStyle: React.CSSProperties} is not assignable to parameter
type HTMLAttributes<HTMLElement> | undefined 
Run Code Online (Sandbox Code Playgroud)

错误的地方:

上面第一个错误

上面第二个错误

我尝试了不同的方法,添加 null 检查并提前返回 null,添加类型断言as ReactNodeas ReactElement. 但我不能让 TypeScipt 选择我在ofcloneElement中看到的方法的另一个定义index.d.ts@types/React

问题

我怎样才能正确声明这个组件以使 TypeScript 错误消失?如果可能的话,我想在没有类型断言的情况下做到这一点。如果可能的话,我需要在没有任何 NPM 更新的情况下执行此操作(可能会考虑进行小更新)。

使用中的包:

  • “@types/react”:“16.9.1”,
  • “反应”:“16.9.0”,
  • “打字稿”:“3.8.2”,