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

React Native中ApolloClient配置createUploadLink与WebSocketLink报错求助

React Native中配置Apollo Client的createUploadLink时出现类型不兼容错误

我正在React Native应用中实现文件上传功能,打算使用createUploadLink替代传统的createHttpLink,但在配置Apollo Client时遇到了类型不兼容的错误。下面是我的当前配置代码:

import SInfo from "react-native-sensitive-info"; 
import Config from "react-native-config"; 
import { InMemoryCache, ApolloClient } from "apollo-boost"; 
import { createHttpLink } from "apollo-link-http"; 
import { createUploadLink } from "apollo-upload-client"; 
import { WebSocketLink } from "apollo-link-ws"; 
import { setContext } from "apollo-link-context"; 
import { getMainDefinition } from "apollo-utilities"; 
import { split } from "apollo-link"; 

let token: any; 
const getToken = async () => { 
  if (token != null) { 
    return token; 
  } 
  token = await SInfo.getItem("ACCESS_TOKEN", {}); 
  return token; 
}; 

export const cache = new InMemoryCache(); 

// Create a WebSocket link: 
const wsLink = new WebSocketLink({ 
  uri: Config.SUBSCRIPTION_SERVER, 
  options: { 
    reconnect: true, 
  }, 
}); 

const httpLink = createHttpLink({ uri: Config.GRAPHQL_SERVER }); 
const uploadLink = createUploadLink({ uri: Config.GRAPHQL_SERVER }); 

const authLink = setContext(async (_, { headers }) => { 
  await getToken(); 
  return { 
    headers: { 
      ...headers, 
      authorization: token ? `Bearer ${token}` : null, 
    }, 
  }; 
}); 

const linkConcated = authLink.concat(httpLink); 

// using the ability to split links, you can send data to each link 
// depending on what kind of operation is being sent 
const link = split( 
  // split based on operation type 
  ({ query }) => { 
    const definition = getMainDefinition(query); 
    return ( 
      definition.kind === "OperationDefinition" && 
      definition.operation === "subscription" 
    ); 
  }, 
  wsLink, 
  linkConcated 
); 

export const client = new ApolloClient({ 
  link, 
  cache, 
});

尝试替换createHttpLink为createUploadLink,以及尝试用ApolloLink.from()组合链接后,都出现了以下TypeScript错误:

const uploadLink: ApolloLink 
Argument of type 'ApolloLink' is not assignable to parameter of type 'ApolloLink | RequestHandler'. 
Type 'import("/home/musayyab/Desktop/projects/Talent/Native-App/app/node_modules/@apollo/client/link/core/ApolloLink").ApolloLink' is not assignable to type 'import("/home/musayyab/Desktop/projects/Talent/Native-App/app/node_modules/apollo-link/lib/link").ApolloLink'. 
Types of property 'split' are incompatible. 
Type '(test: (op: import("/home/musayyab/Desktop/projects/Talent/Native-App/app/node_modules/@apollo/client/link/core/types").Operation) => boolean, left: import("/home/musayyab/Desktop/projects/Talent/Native-App/app/node_modules/@apollo/client/link/core/ApolloLink").ApolloLink | import("/home/musayyab/Desktop/projects/Ta...' is not assignable to type '(test: (op: import("/home/musayyab/Desktop/projects/Talent/Native-App/app/node_modules/apollo-link/lib/types").Operation) => boolean, left: import("/home/musayyab/Desktop/projects/Talent/Native-App/app/node_modules/apollo-link/lib/link").ApolloLink | import("/home/musayyab/Desktop/projects/Talent/Native-App/app/node...'. 
Types of parameters 'test' and 'test' are incompatible. 
Types of parameters 'op' and 'op' are incompatible. 
Property 'toKey' is missing in type 'import("/home/musayyab/Desktop/projects/Talent/Native-App/app/node_modules/@apollo/client/link/core/types").Operation' but required in type 'import("/home/musayyab/Desktop/projects/Talent/Native-App/app/node_modules/apollo-link/lib/types").Operation'.ts(2345) 
types.d.ts(24, 5): 'toKey' is declared here.

问题原因

这个错误是由于依赖版本不匹配导致的类型冲突:你项目中同时存在@apollo/client(新版)和旧版的apollo-link相关包,两者的ApolloLink类型定义不兼容,尤其是Operation类型的toKey属性差异。

解决步骤

  1. 统一依赖版本
    确保你使用的apollo-upload-client版本与@apollo/client兼容。对于@apollo/client v3.x,需要安装apollo-upload-client@^16.0.0及以上版本:

    npm install apollo-upload-client@latest
    # 或者使用yarn
    yarn add apollo-upload-client@latest
    

    同时,移除旧的apollo-link相关包(这些功能已集成到@apollo/client中,无需单独安装):

    npm uninstall apollo-link apollo-link-http apollo-link-ws apollo-link-context
    # yarn
    yarn remove apollo-link apollo-link-http apollo-link-ws apollo-link-context
    
  2. 修正Apollo Client配置代码
    用@apollo/client提供的工具替代旧包,并且只保留createUploadLink作为HTTP链接(它完全兼容普通GraphQL请求,同时支持文件上传):

    import SInfo from "react-native-sensitive-info";
    import Config from "react-native-config";
    import { InMemoryCache, ApolloClient, split, ApolloLink } from "@apollo/client";
    import { createUploadLink } from "apollo-upload-client";
    import { WebSocketLink } from "@apollo/client/link/ws";
    import { setContext } from "@apollo/client/link/context";
    import { getMainDefinition } from "@apollo/client/utilities";
    
    let token: any;
    const getToken = async () => {
      if (token != null) {
        return token;
      }
      token = await SInfo.getItem("ACCESS_TOKEN", {});
      return token;
    };
    
    export const cache = new InMemoryCache();
    
    // WebSocket链接用于订阅
    const wsLink = new WebSocketLink({
      uri: Config.SUBSCRIPTION_SERVER,
      options: {
        reconnect: true,
        connectionParams: async () => {
          await getToken();
          return {
            authorization: token ? `Bearer ${token}` : null,
          };
        },
      },
    });
    
    // 使用createUploadLink替代createHttpLink
    const uploadLink = createUploadLink({
      uri: Config.GRAPHQL_SERVER,
    });
    
    // 认证链接
    const authLink = setContext(async (_, { headers }) => {
      await getToken();
      return {
        headers: {
          ...headers,
          authorization: token ? `Bearer ${token}` : null,
        },
      };
    });
    
    // 组合认证链接和上传链接
    const httpAuthLink = authLink.concat(uploadLink);
    
    // 根据操作类型拆分链接:订阅用WS,其他用HTTP(uploadLink)
    const link = split(
      ({ query }) => {
        const definition = getMainDefinition(query);
        return (
          definition.kind === "OperationDefinition" &&
          definition.operation === "subscription"
        );
      },
      wsLink,
      httpAuthLink
    );
    
    export const client = new ApolloClient({
      link,
      cache,
    });
    
  3. 验证配置
    重启TypeScript服务和React Native开发服务器,确保类型错误消失。此时你可以在GraphQL mutations中使用File类型的变量来实现文件上传了。

关键说明

  • createUploadLink是createHttpLink的超集,支持所有普通GraphQL请求的同时,还能处理multipart/form-data类型的文件上传请求,所以不需要同时保留createHttpLink。
  • 所有链接相关的工具都从@apollo/client导入,彻底避免了旧版apollo-link包的类型冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:35:31