使用React Components、apollo-client与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),
datawon'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:
Explicitly check loading/error states first
This tells TypeScript that once you've handled loading and error,datamust 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> );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 TypeScriptdataisn'tundefined:{({ 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.
Customise types properly (without ignoring states)
If you want to define your own props type, include all possible states instead of forcingdatato 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

