首页 > 解决方案 > 如何对包含对象的 props 接口进行 TypeScript 并与 defaultProps 合并

问题描述

我有一个像这样的 TypeScript 道具界面:

interface Props {
  children: ReactNode;
  components?: object;
  mode: string;
  actions: {
    copy: boolean;
    code: boolean;
    refresh: boolean;
    source: boolean;
  };
  source?: string;
  readonly withStyles?: object;
  styles?: object;
}

我有一个相应的 defaultProps 接口,如下所示:

class Box extends Component<Props, State> {
  public static defaultProps = {
    mode: 'full',
    actions: {
      copy: true,
      code: true,
      refresh: true,
      source: true,
    },
  };

  ....

}

用户应该只能指定actions组件的一部分,其余的应该从defaultProps.

例如,如果用户指定:

<Box actions={{ copy: false }} />

我希望 defaultProps 将填补空白以生props.actions成为{ copy: false, code: true, refresh: true, source: true }.

但是,我目前收到一个 TypeScript 错误:Type '{ copy: boolean; }' is missing the following properties from type '{ copy: boolean; code: boolean; refresh: boolean; source: boolean; }': code, refresh, source.

我怎样才能让它正常工作?

TypeScript v.3.2.2
@types/react v16.8.2

标签: reactjstypescript

解决方案


React 没有深入的 defaultProps 检查/合并,TypeScript 不会改变这一点。

处理此问题的一种方法是制作包装器组件:

//pure js

const defaultActions = {
  copy: true,
  paste: false
};

const Box = props => JSON.stringify(props);
const BoxWithDefaultActions = ({ actions, ...rest }) => (
  <Box actions={{ ...defaultActions, ...actions }} {...rest} />
);

const App = () => (
  <>
      <Box actions={{ copy: false }} />
      <BoxWithDefaultActions actions={{ copy: false }} />
  </>
);

/**
Box:
  { "actions": { "copy": false } }
Box with actions:
  { "actions": { "copy": false, "paste": false } }
**/

//HOC or render props component could be even better "solution". 

您可以在 React Github 问题中阅读更多相关信息:https ://github.com/facebook/react/issues/2568


推荐阅读