我有以下代码:
import { Query } from 'react-apollo';
type Post = {
id: string
};
interface Data {
posts: Array<Post>;
}
class PostsQuery extends Query<Data> {}
按以下方式使用上述内容时:
<PostsQuery query={POSTS_QUERY}>
{({ loading, data }) => {
...
{data.posts.map(...)}
...
}
</PostsQuery>
我从流程中收到以下错误:
Error:(151, 27) Cannot get 'data.posts' because property 'posts' is missing in object type [1].
知道为什么吗?
我确实使用flow-typed
将apollo-client_v2.x.x.js
添加到我的项目中
答案 0 :(得分:3)
接续说明如何制作verifiable example and research the problem.
因此看来,react-apollo的这一部分没有以使访问data
内容简单明了的方式键入。好的,那很好,我们可以建议他们进行销毁并检查空数据。同时,我们还可以向id
类型添加Post
属性,以便流程不再抱怨:
({Try-滚动至底部以获取相关代码)
type Post = {
id: string,
title: string;
};
...snip...
// Look ma, no errors
class Search extends React.Component<{}> {
render = () => (
<PostsQuery query={QUERY}>
{({ loading, error, data }) => {
if (error) {
return <p>Error</p>
}
if (loading) return <p>Loading</p>
const nonNullData = (data || {})
const dataWithAllPosts = {allPosts: [], ...nonNullData}
const {allPosts} = dataWithAllPosts
if (allPosts.length == 0) {
return <p>Empty response or something</p>
}
return (
<div>
{allPosts.map(post => {
return <div key={post.id}>{post.title}</div>;
})}
</div>
);
}}
</PostsQuery>
);
}
我对react-apollo库不熟悉,所以我不确定在没有帖子的情况下如何处理这种情况。我刚刚添加了一条消息,如上所述。这种情况很可能永远不会发生(再次,您会比我更了解)。如果是这种情况,您可能要跳过上述某些步骤,而只需使用cast through any声明所需的类型。
答案 1 :(得分:1)
因此,在分析这些类型时,我们要做的第一件事是在flow-typed repo中查找typedef。我继续将react-apollo typedefs复制粘贴到flow.org/try,对其进行了稍微修改(在某个地方添加了any
,将gql
设置为any
),并且能够复制错误:
({Try-滚动到代码底部)
参考relevant lines of the QueryRenderProps
type,我们可以看到为什么流程抛出错误:
{
data: TData | {||} | void,
...
}
看起来数据可以是TData
(可能是您想要的),空对象或未定义。与typescript typings for react-apollo进行交叉检查,我们可以看到类型为何如此:
{
...
// we create an empty object to make checking for data
// easier for consumers (i.e. instead of data && data.user
// you can just check data.user) this also makes destructring
// easier (i.e. { data: { user } })
// however, this isn't realy possible with TypeScript that
// I'm aware of. So intead we enforce checking for data
// like so result.data!.user. This tells TS to use TData
// XXX is there a better way to do this?
data: TData | undefined;
...
}
不幸的是,由于这些链接的极端长度以及stackoverflow对答案长度的限制,我不得不在another answer中继续我的答案。我想这个答案可以用来解释如何开始调试问题。