我尝试使用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<OperationVariables> & Partial<ArticlesFeedResponse>) | 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>;
};
QueryProps:
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
应包含loading
和error
属性。我想错误来自| undefined
部分,但我无法理解为什么这个联盟会出现。
有什么建议吗?
P上。 S.如果我不从ChildProps
导入默认react-apollo/types
,而是使用此更新版本:
type ChildProps<P, R> = P & {
data: QueryProps & R;
mutate?: MutationFunc<R>;
};
我的代码正在运行。我还没有得到的是 - 我做错了什么或者这是react-apollo/types
包中的错误?
答案 0 :(得分:1)
graphql
类型的注释采用<ParentProps, QueryResponse, Variables>
。您正在通过
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