将 React.Components 与 apollo-client 和 TypeScript 一起使用
Using React.Components with apollo-client and TypeScript
我正在尝试使用 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);
schemas/results:
export interface Article {
id: string,
shortText: string,
publicationDate: string
}
export type ArticlesFeedResponse = {
feed: Article[];
}
schemas/queries:
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.
我不明白发生了什么 - 导入的类型是:
儿童道具:
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
应该同时包含 loading
和 error
属性。我想错误来自 | undefined
部分,但我不明白为什么这个联合会出现。
有什么建议吗?
P. S. 如果我不从 react-apollo/types
导入默认值 ChildProps
,而是使用这个更新版本:
type ChildProps<P, R> = P & {
data: QueryProps & R;
mutate?: MutationFunc<R>;
};
我的代码正在运行。我仍然不明白的是 - 我做错了什么或者这是 react-apollo/types
包中的错误?
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
注释是 incorrect/a 错误?值得注意的是,example docs 不进行类型检查。
针对 react-apollo@2.1.9
进行了测试
我正在尝试使用 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);
schemas/results:
export interface Article {
id: string,
shortText: string,
publicationDate: string
}
export type ArticlesFeedResponse = {
feed: Article[];
}
schemas/queries:
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.
我不明白发生了什么 - 导入的类型是:
儿童道具:
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
应该同时包含 loading
和 error
属性。我想错误来自 | undefined
部分,但我不明白为什么这个联合会出现。
有什么建议吗?
P. S. 如果我不从 react-apollo/types
导入默认值 ChildProps
,而是使用这个更新版本:
type ChildProps<P, R> = P & {
data: QueryProps & R;
mutate?: MutationFunc<R>;
};
我的代码正在运行。我仍然不明白的是 - 我做错了什么或者这是 react-apollo/types
包中的错误?
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
注释是 incorrect/a 错误?值得注意的是,example docs 不进行类型检查。
针对 react-apollo@2.1.9