打字稿和反应HOC(高阶组件)

时间:2018-03-16 21:34:23

标签: reactjs typescript

使用withBlueBackground高阶组件,我使用新的shade属性扩展一个函数。 (来自此medium post

shade属性应为'light''dark'

不幸的是,这些打字无法帮助我们进行重构或错误的props定义。

虽然'ORANGE''light''dark'都不匹配,但我附上了一个不会发出警告的示例。

import * as React from 'react';

type ColorShade = 'light' | 'dark';

export interface InjectedBlueBackgroundProps {
  backgroundColor: string;
}

interface WithBlueBackgroundProps {
  shade?: ColorShade;
}

const getBlueShade = (shade?: ColorShade) => {
  switch (shade) {
    case 'dark':
      return 'navy';
    case 'light':
      return 'skyblue';
    default:
      return 'blue';
  }
};

const withBlueBackground = <P extends InjectedBlueBackgroundProps>(
  UnwrappedComponent: React.ComponentType<P>
) =>
  class WithBlueBackground extends React.Component<
    P & WithBlueBackgroundProps
  > {
    render() {
      return (
        <UnwrappedComponent
          {...this.props}
          backgroundColor={getBlueShade(this.props.shade)}
        />
      );
    }
  };

export default withBlueBackground;

// The following line should throw an type error but does not:
export const Demo = withBlueBackground((props: {shade?: 'ORANGE'}) => {
  return <div>{props.backgroundColor}</div>
});

有没有解决方案?

1 个答案:

答案 0 :(得分:2)

让HOC调用的一些事情对我来说似乎很奇怪:

1)在箭头功能

中访问 this。

2)使用HOC作为低阶组件......从HOC的通用道具中访问 this.props.shade

请注意,你想给一些HOC提供一些自己的道具(顶级)和一些注入的道具(低级别)到包裹的组件。

B

演示文件

// main.ts

import React from 'react';

import {Demo} from './demo';

React.render(
  <Demo
    greeting="hello"
    shape="light"
  />,
  document.getElementById('app'),
);

特殊文件

// demo.ts

import React from 'react';

import withBlueBackground, {InjectedBlueBackgroundProps, OwnBlueBackgroundProps} from './withBlueBackground';

interface OwnDemoProps extends OwnBlueBackgroundProps {
  greeting: string;
}

type DemoProps = OwnDemoProps & InjectedBlueBackgroundProps;

const Demo = (props: DemoProps) => (
  <div>{props.greeting + ' ' + props.backgroundColor}</div>
);

const DemoBlue = withBlueBackground<OwnDemoProps>(Demo);

export {DemoBlue as Demo};