【问题标题】:How to make Typescript recognize the type for an Apollo Query如何让 Typescript 识别 Apollo 查询的类型
【发布时间】:2018-11-24 19:52:38
【问题描述】:

我正在尝试让 Apollo 与 TypeScript 集成。 我有一个如下所示的 React 类:

interface Data {
  allVendors: Array<VendorType>;
}

class AllVendorsQuery extends Query<Data> {}

const ShowVendors: React.SFC<> = props => {
  return (
    <AllVendorsQuery query={fetchVendors}>
      {({ loading, error, data: { allVendors } }) => {
        if (loading) {
          return 'Loading...';
        }
        if (error) {
          return `Error! ${error.message}`;
        }

        return (
          allVendors &&
          allVendors.map((vendor, index: number) => {
            return (
              <div key={`${vendor.name}_${index}`}>
                #<strong>{vendor.id}</strong>
                &nbsp;{vendor.name}
              </div>
            );
          })
        );
      }}
    </AllVendorsQuery>
  );
};

export default ShowVendors;

查询是:

export default gql`
  query GetVendors {
    allVendors {
      id
      name
    }
  }
`;

TypeScript 抱怨 [ts] Type 'Data | undefined' has no property 'allVendors' and no string index signature. 出现在这一行:{({ loading, error, data: { allVendors } })

但是,如果我使用 apollo-connect 而不是 Query 组件重构代码,我不会收到来自 TypeScript 的任何抱怨:

import { graphql, compose, QueryResult } from 'react-apollo';

interface ShowVendorsProps {
  data: QueryResult & { allVendors?: VendorType[] };
}

class ShowVendors extends React.Component<ShowVendorsProps> {
  render() {
    const {
      data: { allVendors }
    } = this.props;

    if (allVendors && allVendors.length > 0) {
      return (
        <div>
          {allVendors.map((vendor, index: number) => {
            return (
              <div key={`${vendor.name}_${index}`}>
                #<strong>{vendor.id}</strong>
                &nbsp;{vendor.name}
              </div>
            );
          })}
        </div>
      );
    } else {
      return 'Loading';
    }
  }
}

export default compose(graphql(fetchVendors))(ShowVendors);

这两者有什么区别?如何重写第一条语句的类型?

【问题讨论】:

    标签: reactjs typescript apollo react-apollo


    【解决方案1】:

    有一个小型库和 CLI 可以为服务器(根据您的架构)和客户端(根据您的架构和 GraphQL 文档)生成 TypeScript 类型。它还生成解析器签名并且非常可定制。

    你可以在这里试试:https://github.com/dotansimha/graphql-code-generator

    这里有一篇关于该软件包的博文; https://medium.com/the-guild/graphql-code-generator-for-typescript-react-apollo-7b225672588f

    其背后的想法是让开发人员充分利用 GraphQL 和生成的类型,并更轻松地自定义生成的输出。

    它还可以生成带有您需要的类型的 react-apollo 组件。

    【讨论】:

      【解决方案2】:

      由于您在第一个代码块中使用data: { allVendors } 解构data,TypeScript 会抱怨因为data 可能未定义,例如当数据仍在加载时。

      因此,如果 TS 不抱怨,您可以在加载检查后进行解构,默认值为 allVendors,类似于:

      interface Data {
        allVendors: Array<VendorType>;
      }
      
      class AllVendorsQuery extends Query<Data> {}
      
      const ShowVendors: React.SFC<> = props => {
        return (
          <AllVendorsQuery query={fetchVendors}>
            {({ loading, error, data }) => {
              if (loading) {
                return 'Loading...';
              }
              if (error) {
                return `Error! ${error.message}`;
              }
      
              // If data is not undefined, then it sets allVendors accordingly.
              // Otherwise it sets it to null (which you check for anyways below)             
              const {allVendors} = data || {allVendors: null}; 
      
              return (
                allVendors &&
                allVendors.map((vendor, index: number) => {
                  return (
                    <div key={`${vendor.name}_${index}`}>
                      #<strong>{vendor.id}</strong>
                      &nbsp;{vendor.name}
                    </div>
                  );
                })
              );
            }}
          </AllVendorsQuery>
        );
      };
      
      export default ShowVendors;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-10-27
        • 2014-05-17
        • 2020-11-05
        • 2020-02-07
        • 2017-08-17
        • 2017-04-16
        • 2012-02-01
        相关资源
        最近更新 更多