簡體   English   中英

如何使用 react 和 typescript 創建通用箭頭 function

[英]How to create a generic arrow function with react and typescript

我正在嘗試為 apollo graphql 結果創建一個通用包裝器組件。 我希望這個包裝器等待查詢成功完成,然后呈現一個傳遞給道具的組件。 傳入的組件應該具有QueryResult<T>類型的道具。

這個代碼片段在 Col 66 上給了我一個錯誤說

找不到名稱“T”.ts(2304)

import React from 'react';
import { QueryResult } from 'react-apollo';
import { useSandboxContext } from 'src/js/shared/components/SandboxContext';
import { ErrorContent } from 'src/js/shared/components/ErrorContent';
import { PageSpinner } from 'src/js/shared/components/PageSpinner';

interface WrapperComponentProps<T> extends QueryResult<T> {
  // TODO: figure out how to specify that the wrapped component takes the results
  // Something like this `React.ReactType<QueryResult<T>>` but this causes errors
  wrappedComponent: React.ReactType;
}

// Getting an error from `React.FC<WrapperComponentProps<T>>`
// `Cannot find name 'T'.ts(2304)`
export const ApolloResultWrapper: React.FC<WrapperComponentProps<T>> = <T extends object>(props: WrapperComponentProps<T>) => {
  const sandbox = useSandboxContext();

  if (props.error) {
    sandbox.logger.error('query failed', props.error);

    return <ErrorContent />
  }
  if (props.loading) {
    return <PageSpinner />;
  }

  if (!props.data) {
    return <ErrorContent />
  }

  // TODO: figure out how to spread all the props except wrappedComponent
  return <props.wrappedComponent {...props} wrappedComponent={undefined} />;
}

如果錯誤是關於<T extends object>的地方嘗試將類型轉換<T extends object>更改為.... as T extends object

https://www.typescriptlang.org/docs/handbook/jsx.html#the-as-operator

終於設法解決了問題

interface WrappedComponentProps<T> {
  data: T
}

interface WrapperComponentProps<T, K> {
  apolloResult: QueryResult<T>;
  wrappedComponent: React.ComponentType<WrappedComponentProps<T> & K>;
  componentProps: Omit<K, keyof WrappedComponentProps<T>>;
}

type ComponentProps<T, K> = React.PropsWithChildren<WrapperComponentProps<T, K>>;

export const ApolloResultWrapper = <T extends object, K = {}>(props: ComponentProps<T, K>) => {
  const sandbox = useSandboxContext();

  if (props.apolloResult.error) {
    sandbox.logger.error('stuff broke', props.apolloResult.error);

    return <ErrorContent />
  }
  if (props.apolloResult.loading) {
    return <PageSpinner />;
  }
  if (!props.apolloResult.data) {
    return <ErrorContent />
  }

  return <props.wrappedComponent
    children={props.children}
    data={props.apolloResult.data}
    {...props.componentProps as K}
  />;
}

暫無
暫無

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

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