You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用React Components、apollo-client与TypeScript遇类型错误求助

Understanding the Type Error with react-apollo's Query Component in TypeScript

Hey there! Let's unpack what's happening with your component and that type error you're seeing.

First: Why the undefined is in the union type

This isn't a bug in react-apollo/types—it's intentional behavior tied to how Apollo Client works.

When using the Query component, Apollo passes a set of props to your render function that includes loading, error, and data. The data property is marked as optional (and thus can be undefined) because:

  • During the initial loading state, there's no data yet
  • If the query fails (network error, invalid response), data won't be present either

The union type you're seeing ((QueryProps<OperationVariables> & Partial<ArticlesFeedResponse>) | undefined) likely comes from how TypeScript infers the render props when you don't explicitly narrow down the possible states.

Why making data required "fixes" the error

When you customise ChildProps to mark data as required, you're essentially telling TypeScript to ignore the cases where data might be missing. This silences the type error, but it skips handling critical states like loading or errors—something that could lead to runtime bugs (like trying to access data.articles when data is undefined).

The correct way to handle this

Instead of forcing data to be required, lean into TypeScript's type narrowing to handle all possible states:

  1. Explicitly check loading/error states first
    This tells TypeScript that once you've handled loading and error, data must exist:

    import { Query } from 'react-apollo';
    import { ARTICLES_QUERY } from './your-queries';
    import { ArticlesFeedResponse } from './your-schema-types';
    
    const ArticlesList = () => (
      <Query<ArticlesFeedResponse> query={ARTICLES_QUERY}>
        {({ loading, error, data }) => {
          if (loading) return <div>Loading articles...</div>;
          if (error) return <div>Oops! {error.message}</div>;
          // TypeScript now knows data is not undefined here
          return (
            <ul>
              {data.articles.map(article => (
                <li key={article.id}>{article.title}</li>
              ))}
            </ul>
          );
        }}
      </Query>
    );
    
  2. Use non-null assertion (with caution)
    If you're absolutely certain the query will always return data (e.g., you have a fallback or the query is guaranteed to succeed), you can use the non-null assertion operator ! to tell TypeScript data isn't undefined:

    {({ data }) => {
      // Only do this if you're 100% sure data exists
      return <ArticlesList articles={data!.articles} />;
    }}
    

    Note: This is risky—if the query ever fails, you'll get a runtime error.

  3. Customise types properly (without ignoring states)
    If you want to define your own props type, include all possible states instead of forcing data to be required:

    import { ApolloError } from 'apollo-client';
    
    type ArticlesQueryRenderProps = {
      loading: boolean;
      error?: ApolloError;
      data?: ArticlesFeedResponse;
    };
    

Wrap-up

The undefined in the union type is not a bug—it's Apollo's type system correctly reflecting the reality of asynchronous data fetching. Your initial type error was a reminder to handle the loading and error states that come with any GraphQL query. While making data required silences the error, it's not the best practice because it skips these critical edge cases.

内容的提问来源于stack exchange,提问作者Eternal1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:15:22