【问题标题】:Using React.Components with apollo-client and TypeScript将 React.Components 与 apollo-client 和 TypeScript 一起使用
【发布时间】:2018-07-04 14:40:42
【问题描述】:

我正在尝试使用 apollo-client 和 TypeScript 构建一个简单的 React 组件。

这个组件只是查询文章列表并显示它们。代码如下:

import * as React from 'react';
import graphql from "react-apollo/graphql";
import { ARTICLES_FEED } from "../schemas/queries";
import { Article, ArticlesFeedResponse } from "../schemas/results";
import { ChildProps } from "react-apollo/types";

const AppQL = graphql<ArticlesFeedResponse, {}>(ARTICLES_FEED);

class App extends React.Component<ChildProps<{}, ArticlesFeedResponse>, {}> {
    render() {
        const { loading, feed, error } = this.props.data;

        if (loading) return <div>loading</div>;
        if (error) return <div>{ error }</div>;
        return (
            <React.Fragment>
                <h1>It works!</h1>
                {this.props.data && feed.map( (article:Article) => (
                    <div>{article.shortText}</div>
                ))}
            </React.Fragment>
        );
    }
}

export default AppQL(App);

模式/结果:

export interface Article {
    id: string,
    shortText: string,
    publicationDate: string
}

export type ArticlesFeedResponse = {
  feed: Article[];
}

模式/查询:

import gql from 'graphql-tag'

export const ARTICLES_FEED = gql`
    query ArticlesFeed {
        feed {
            id
            shortText
            publicationDate
        }
    }
`;

尽管如此,签名匹配,但我仍然收到错误:

Type '(QueryProps&lt;OperationVariables&gt; &amp; Partial&lt;ArticlesFeedResponse&gt;) | undefined' has no property 'loading' and no string index signature.

我不明白发生了什么 - 导入的类型是:

ChildProps:

export declare type ChildProps<P, R> = P & {
    data?: QueryProps & Partial<R>;
    mutate?: MutationFunc<R>;
};

查询属性:

export interface QueryProps<TVariables = OperationVariables> {
    error?: ApolloError;
    networkStatus: number;
    loading: boolean;
    variables: TVariables;
    fetchMore: (fetchMoreOptions: FetchMoreQueryOptions & FetchMoreOptions) => Promise<ApolloQueryResult<any>>;
    refetch: (variables?: TVariables) => Promise<ApolloQueryResult<any>>;
    startPolling: (pollInterval: number) => void;
    stopPolling: () => void;
    subscribeToMore: (options: SubscribeToMoreOptions) => () => void;
    updateQuery: (mapFn: (previousQueryResult: any, options: UpdateQueryOptions) => any) => void;
}

所以ChildProps 应该同时包含loadingerror 属性。我猜| undefined 部分有一个错误,但我不明白为什么会出现这个联合。

有什么建议吗?

P。 S. 如果我不从react-apollo/types 导入默认ChildProps,而是使用这个更新版本:

type ChildProps<P, R> = P & {
    data: QueryProps & R;
    mutate?: MutationFunc<R>;
};

我的代码正在运行。我仍然没有得到的是 - 我做错了什么还是react-apollo/types 包中的错误?

【问题讨论】:

    标签: typescript react-apollo apollo-client


    【解决方案1】:

    graphql 类型注解采用&lt;ParentProps, QueryResponse, Variables&gt;。你通过了它

    graphql<ArticlesFeedResponse, {}>(ARTICLES_FEED)
    

    什么时候你应该通过它

    graphql<{} ArticlesFeedResponse>(ARTICLES_FEED)
    

    其次,正如您所指出的,ChildProps 注释指出 data 可以是 undefined。考虑到这一点,一切都应该进行类型检查。

    class App extends React.Component<ChildProps<{}, ArticlesFeedResponse>, {}> {
      render() {
        if (!this.props.data) {
          return;
        }
    
        const { loading, feed, error } = this.props.data;
    
        if (loading) return <div>loading </div>;
        if (error) return <div>{error} </div>;
    
        return (
          <React.Fragment>
          <h1>It works!</h1>
            {
              feed && feed.map((article: Article) => (
                <div>{ article.shortText } </div>
              ))
            }
          </React.Fragment>
        );
      }
    }
    

    或者,标记const { loading, feed, error } = this.props.data!; 告诉类型检查器它不会是未定义的。 AFAIK,data 属性永远不应该是未定义的,所以你可以安全地将它标记为存在 this.props.data!, ...也许ChildProps 注释不正确/一个错误?值得注意的是,example docs 不进行类型检查。

    针对react-apollo@2.1.9进行测试

    【讨论】:

    • 这是 apollo-graphql 中的一个错误,据我所知已修复。不过还是谢谢你的回答。
    • 我仍然可以对react-apollo@2.1.9进行复制,所以开了一张票here
    • 事实上,我已经停止使用带有react-apollo 的TS,因为它产生的问题远远多于解决的问题(至少对我而言),现在我只使用npmjs.com/package/prop-types 来检查道具运行时,就是这样。
    猜你喜欢
    • 2020-03-31
    • 2018-09-05
    • 2021-01-11
    • 2017-12-22
    • 2021-06-25
    • 1970-01-01
    • 2018-01-20
    • 2021-04-27
    • 2020-04-17
    相关资源
    最近更新 更多