Reactjs 如何将中继(graphql)连接映射到边缘';将泛型与Typescript一起使用的s节点

Reactjs 如何将中继(graphql)连接映射到边缘';将泛型与Typescript一起使用的s节点,reactjs,typescript,graphql,react-apollo,relayjs,Reactjs,Typescript,Graphql,React Apollo,Relayjs,我最近一直在试验React、GraphQL、Apollo和Relay一致性查询 现在我有一个GraphQL后端,它有一个简单的GraphQL模式,带有一些连接查询,用于返回可以使用中继服务器规范分页的实体列表 在前端,我发现自己在提出上述问题后重复了一遍 代码通常如下所示: type isDefined = <T>(value: T | null | undefined): value is T => value !== null && value !== un

我最近一直在试验React、GraphQL、Apollo和Relay一致性查询

现在我有一个GraphQL后端,它有一个简单的GraphQL模式,带有一些连接查询,用于返回可以使用中继服务器规范分页的实体列表

在前端,我发现自己在提出上述问题后重复了一遍 代码通常如下所示:

type isDefined = <T>(value: T | null | undefined): value is T => value !== null && value !== undefined;

export const AppleListComponent: React.FC = () => {
  const { data } = useAppleQuery(); // FWIW, generating this with graphql-code-generator
  const apples = data && data.apples;
  const appleNodes = apples && apples.edges.map(apple => (
    apple ? apple.node : undefined
  )).filter(apple => isDefined(apple));

  return (
    <div>
      {appleNodes && appleNodes.map(apple => (
        <p key={apple.text}>{apple.text}</p>
      ))}
    </div>
  );
};
type isDefined=(值:T | null | undefined):值为T=>value!==空值和值!==未定义;
export const AppleListComponent:React.FC=()=>{
const{data}=useAppleQuery();//FWIW,使用graphql代码生成器生成
const apples=data&&data.apples;
常量appleNodes=apples&&apples.edges.map(apple=>(
apple?apple.node:未定义
)).filter(apple=>isDefined(apple));
返回(
{appleNodes&&appleNodes.map(苹果=>(

{apple.text}

))} ); };
由于中继规范要求边缘和节点可以为空,因此检查存在性是必要的

我发现自己经常重复这种从中继格式到简单的节点数组格式的转换。 我决定看看是否可以创建一个helper函数,该函数接受符合连接接口的内容,并返回未定义的节点或映射节点列表

那次尝试是这样的:

type Maybe<T> = T | null;
type isDefined = <T>(value: T | null | undefined): value is T => value !== null && value !== undefined;

type Connection<T> = Maybe<{ edges: Array<Maybe<{ node: Maybe<T> }>>}>;

export const connectionToNodes = <T>(connection: Connection<T>): Maybe<T[]> => (
  connection && connection.edges.map(edge => (
    edge ? edge.node : undefined
  )).filter(isDefined)
);
type Maybe=T | null;
类型isDefined=(值:T | null | undefined):值为T=>value!==空值和值!==未定义;
类型连接=可能;
export const connectionnodes=(连接:connection):Maybe=>(
连接和连接.edges.map(edge=>(
edge?edge.node:未定义
)).过滤器(已定义)
);
这允许前一个组件成为

export const AppleListComponent: React.FC = () => {
  const { data } = useAppleQuery();
  const apples = data && data.apples;
  const appleNodes = connectionToNodes(apples);

  return (
    <div>
      {appleNodes && appleNodes.map(apple => (
        <p key={apple.text}>{apple.text}</p>
      ))}
    </div>
  );
};
export const AppleListComponent:React.FC=()=>{
const{data}=useAppleQuery();
const apples=data&&data.apples;
常量appleNodes=连接节点(苹果);
返回(
{appleNodes&&appleNodes.map(苹果=>(

{apple.text}

))} ); };
我这里的问题是,我的连接类型当然不完全匹配 我要传递的类型有更多属性,如下所示:

Maybe<(
  { __typename?: 'AppleConnection' }
  & { edges: Array<Maybe<(
    { __typename?: 'AppleEdge' }
    & { node: Maybe<{ __typename?: 'AppleType' }
      & { __typename?: 'QuestionType' }
        & Pick<QuestionType, 'text'>
    > }
  )>> }
)>
也许吧
所以我最终得到了关于任何类型的问题的错误,以及 我传递给
connectionNodes
的内容与指定的类型不匹配

我的直觉是,我需要说我的类型
T
是另一种类型的子类型,即 出于应用目的,我不在乎它是
Apple
还是
Pear
连接/边缘/节点,但我希望它最终被推断出来-有什么建议吗
关于如何实现此目的?

请尝试使用此帮助程序从连接中提取节点

export type ExtractNode<T extends { edges: any }> = NonNullable<NonNullable<T['edges'][number]>['node']>;
导出类型ExtractNode=不可为空;
用法

type Post=ExtractNode

尝试使用此帮助程序从连接中提取节点

export type ExtractNode<T extends { edges: any }> = NonNullable<NonNullable<T['edges'][number]>['node']>;
导出类型ExtractNode=不可为空;
用法

type Post=ExtractNode