簡體   English   中英

反應 HOC 類型推斷

[英]React HOC type inferring

我想創建一個返回高階組件的高階函數

在下面的示例中,我創建了一個validateSearchParams函數,該函數創建了一個可用於包裝組件的函數 但是,Typescript (3.7.2) 無法正確推斷類型。

export function validateSearchParams<Props extends { location: Location }>(
  test: (searchParams: URLSearchParams) => boolean,
  redirectTo: string,
): (Cmp: React.ComponentType<Props>) => React.ComponentType<Props> {
  return (Cmp) => (props) => {
    const searchParams = new URLSearchParams(props.location.search);

    if (!test(searchParams)) {
      return <Redirect to={redirectTo} />;
    }

    return <Cmp {...props} />;
  };
}

export const Test: React.FC<{ something: boolean; location: Location }> = () => null;

// This is OK
validateSearchParams<{ something: boolean; location: Location }>(
  (searchParams) => !!searchParams.get('foo'),
  'hxxp://somewhere',
)(Test);

// ...but without an explicit type it does not compile
validateSearchParams((searchParams) => !!searchParams.get('foo'), 'http://test.example')(Test);
                                                                                         ^^^^

在最后一行中,我收到以下錯誤:

Argument of type 'FC<{ something: boolean; location: Location; }>' is not assignable to
parameter of type 'ComponentType<{ location: Location; }>'.
  Type 'FC<{ something: boolean; location: Location; }>' is not assignable to type
'FunctionComponent<{ location: Location; }>'.
    Types of parameters 'props' and 'props' are incompatible.
      Type 'PropsWithChildren<{ location: Location; }>' is not assignable to type
'PropsWithChildren<{ something: boolean; location: Location; }>'.
        Property 'something' is missing in type 'PropsWithChildren<{ location: Location; }>' but
required in type '{ something: boolean; location: Location; }'.ts(2345)

通過將Cmp合並到參數列表中,我還能夠創建一個更簡單的 HOC 版本:

export function validateSearchParams2<Props extends { location: Location; match: match<any> }>(
  Cmp: React.ComponentType<Props>,
  test: (searchParams: URLSearchParams) => boolean,
  redirectTo: string,
): React.ComponentType<Props> {
  return (props) => {
    const searchParams = new URLSearchParams(props.location.search);

    if (!test(searchParams)) {
      return <Redirect to={redirectTo} />;
    }

    return <Cmp {...props} />;
  };
}
export const Test: React.FC<{ something: boolean; location: Location }> = () => null;

validateSearchParams2(Test, (searchParams) => !!searchParams.get('foo'), 'hxxp://somewhere');

...但是有沒有辦法讓validateSearchParams的第一個版本在沒有顯式類型的情況下工作?

現在泛型類型Props設置在函數validateSearchParams 您想將泛型移動到返回的函數。 基本上validateSearchParams不是一個通用函數,但它返回一個通用 HOC。

export function validateSearchParams(
  test: (searchParams: URLSearchParams) => boolean,
  redirectTo: string,
): <Props extends { location: Location }>(Cmp: React.ComponentType<Props>) => React.ComponentType<Props> {
...

現在您不需要設置顯式類型,因為它可以從您調用它的組件中推斷出來。

打字稿游樂場鏈接

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM