使用来自React HOC的类型正确发布

时间:2019-05-05 19:02:27

标签: reactjs typescript

使用HOC时,我的类型正确时遇到一些问题。我有这个HOC

export interface IWithLangProps {
    lang: ILang;
}

const withLang = <T extends object>(Comp: React.ComponentType<T>):
    React.ComponentClass<T & IWithLangProps, any> | React.FunctionComponent<T & IWithLangProps> =>
     class WrapperComponent extends Component<T & IWithLangProps> {
        render(): JSX.Element {
            return (
                <LangConsumer>
                    {(value: IWithLangProps): JSX.Element =>
                        <Comp {...this.props as T} lang={value.lang} />
                    }
                </LangConsumer>
            );

    }
};

现在我有一个使用HOC的组件。

export interface IGridSearchProps {
    searchDelay?: number;
    onChange: (value: string) => void;
}

/**
 * GridSearch for displaying search field on data grids
 */
const GridSearch = (props: IGridSearchProps): JSX.Element => {
    const {
        onChange,
        searchDelay = 300,
        lang, // Typescript errors here since it cant find lang provided by the HOC
    } = props;

    return (
        <Search
            placeholder={lang.trans('s.search_the_table')}
            onChange={onChange}
            searchDelay={searchDelay}
        />
    );
};

GridSearch.displayName = 'GridSearch';

export default withLang<IGridSearchProps>(GridSearch);

这是我的问题。如何获得GridSearch来正确了解lang?我尝试使用IGridSearchProps扩展IWithLangProps,但是如果使用GridSearch,则任何使用lang的组件都希望{{1}}包含在道具中。

1 个答案:

答案 0 :(得分:1)

由于GridSearch需要lang,因此它应该在GridSearch的道具中。 withLang然后可以使用lang从生成的组件的道具中删除Omit

export interface IWithLangProps {
  lang: ILang;
}
type Omit<T, K extends PropertyKey> = Pick<T, Exclude<keyof T, K>> // Included in 3.5 
const withLang = <T extends object>(Comp: React.ComponentType<T>): React.ComponentType<Omit<T, keyof IWithLangProps>> =>
  class WrapperComponent extends Component<Omit<T, keyof IWithLangProps>> {
      render(): JSX.Element {
          return (
              <LangConsumer>
                  {(value: IWithLangProps): JSX.Element =>
                      <Comp {...this.props as T} lang={value.lang} />
                  }
              </LangConsumer>
          );

  }
};
export interface IGridSearchProps extends IWithLangProps{
  searchDelay?: number;
  onChange: (value: string) => void;
}

/**
* GridSearch for displaying search field on data grids
*/
const GridSearch = (props: IGridSearchProps): JSX.Element => {
  const {
      onChange,
      searchDelay = 300,
      lang, // Typescript errors here since it cant find lang provided by the HOC
  } = props;

  return (
      <Search
          placeholder={lang.trans('s.search_the_table')}
          onChange={onChange}
          searchDelay={searchDelay}
      />
  );
};

GridSearch.displayName = 'GridSearch';

export default withLang(GridSearch);