TypeScript重载函数类型不兼容错误排查求助
问题背景
定义了重载函数类型QueryGrouprequestsOverloadI及实现函数queryGrouprequests,同时有对应的ListGrouprequestsQuery类型定义,运行时触发类型不兼容错误。
重载类型与函数实现代码
type QueryGrouprequestsOverloadI = { ( variables: ListGrouprequestsQueryVariables, limit?: number, returnPartion?: false ): Promise<ListGrouprequestsQuery['listGrouprequests']['items']> ( variables: ListGrouprequestsQueryVariables, limit?: number, returnPartion?: true ): Promise<ListGrouprequestsQuery['listGrouprequests']> } export const queryGrouprequests: QueryGrouprequestsOverloadI = async ( variables: ListGrouprequestsQueryVariables, limit: number = Infinity, returnPartion = false ) => { let res = await queryFunction< ListGrouprequestsQueryVariables, ListGrouprequestsQuery >(listGrouprequests, variables) if (returnPartion) return res.listGrouprequests let result = [...res.listGrouprequests.items] if (result.length >= limit) return result while (res.listGrouprequests.nextToken) { res = await queryFunction< ListGrouprequestsQueryVariables, ListGrouprequestsQuery >(listGrouprequests, { ...variables, nextToken: res.listGrouprequests.nextToken, }) result = [...result, ...res.listGrouprequests.items] if (result.length >= limit) return result } return result }
ListGrouprequestsQuery类型定义
export type ListGrouprequestsQuery = { listGrouprequests?: { __typename: "ModelGrouprequestConnection", items: Array< { __typename: "Grouprequest", id: string, requesterId: string, groupId: string, consent_end?: string | null, consent_start?: string | null, meteringpoint: string, isRemoved?: boolean | null, removedDate?: string | null, meteringpointid: string, consumption?: boolean | null, consentId?: string | null, generation_type?: Generationtypes | null, splitting_active?: string | null, splitting_new?: string | null, data_completed?: string | null, status: Userstatus, process_protocol?: Array< { __typename: "Protocolitem", date: string, message_type: string, message: string, response_code: string, } | null > | null, e_producer_item_id?: number | null, e_product_item_id?: number | null, e_product_id?: number | null, e_monthly_product_item_id?: number | null, e_monthly_product_id?: number | null, e_initial_product_id?: number | null, e_initial_product_item_id?: number | null, e_meteringpoint_id?: number | null, hasIndividualPrice?: boolean | null, new_monthly_cost_date?: string | null, new_initial_cost_date?: string | null, new_price_date?: string | null, new_initial_cost?: number | null, new_monthly_cost?: number | null, new_price?: number | null, process?: Prozessstatus | null, createdAt: string, updatedAt: string, } | null >, nextToken?: string | null, } | null, };
报错信息
Type '(variables: ListGrouprequestsQueryVariables, limit?: number, returnPartion?: boolean) => Promise<{ __typename: "ModelGrouprequestConnection"; items: { ...; }[]; nextToken?: string; } | { ...; }[]>' is not assignable to type 'QueryGrouprequestsOverloadI'.
Type 'Promise<{ __typename: "ModelGrouprequestConnection"; items: { __typename: "Grouprequest"; id: string; requesterId: string; groupId: string; consent_end?: string; consent_start?: string; meteringpoint: string; ... 28 more ...; updatedAt: string; }[]; nextToken?: string; } | { ...; }[]>' is not assignable to type 'Promise<{ __typename: "Grouprequest"; id: string; requesterId: string; groupId: string; consent_end?: string; consent_start?: string; meteringpoint: string; isRemoved?: boolean; removedDate?: string; ... 26 more ...; updatedAt: string; }[]>'.
Type '{ __typename: "ModelGrouprequestConnection"; items: { __typename: "Grouprequest"; id: string; requesterId: string; groupId: string; consent_end?: string; consent_start?: string; meteringpoint: string; ... 28 more ...; updatedAt: string; }[]; nextToken?: string; } | { ...; }[]' is not assignable to type '{ __typename: "Grouprequest"; id: string; requesterId: string; groupId: string; consent_end?: string; consent_start?: string; meteringpoint: string; isRemoved?: boolean; removedDate?: string; meteringpointid: string; ... 25 more ...; updatedAt: string; }[]'.
Type '{ __typename: "ModelGrouprequestConnection"; items: { __typename: "Grouprequest"; id: string; requesterId: string; groupId: string; consent_end?: string; consent_start?: string; meteringpoint: string; ... 28 more ...; updatedAt: string; }[]; nextToken?: string; }' is missing the following properties from type '{ __typename: "Grouprequest"; id: string; requesterId: string; groupId: string; consent_end?: string; consent_start?: string; meteringpoint: string; isRemoved?: boolean; removedDate?: string; meteringpointid: string; ... 25 more ...; updatedAt: string; }[]': length, pop, push, concat, and 29 more.ts(2322)
错误原因
重载参数的字面量类型与实现参数不匹配
重载类型里returnPartion用的是false/true字面量类型,用来区分两个分支的返回类型;但函数实现中returnPartion的参数类型是boolean(默认值为false),TypeScript无法将布尔类型参数和字面量类型的重载分支关联,导致编译器认为函数返回的是两个重载分支类型的联合,而非根据参数动态返回对应类型,触发类型不兼容。未处理
listGrouprequests的空值/可选情况ListGrouprequestsQuery里listGrouprequests是可选属性且可能为null,但重载类型和函数实现都直接访问res.listGrouprequests.items或返回res.listGrouprequests,既存在运行时空指针风险,也让类型系统无法准确推断返回类型。返回类型的隐式联合与重载分支冲突
函数实现的返回类型被推断为Promise<ModelGrouprequestConnection | Grouprequest[]>,但重载要求returnPartion为false时仅返回Grouprequest[],为true时仅返回ModelGrouprequestConnection。因为参数类型的问题,编译器无法确认返回值对应哪个重载分支,所以认为联合类型无法匹配任意一个重载分支的单一返回类型,从而报错。
修复方案
将实现参数改为字面量联合类型
修改returnPartion参数类型为true | false,让编译器能关联到对应的重载分支:export const queryGrouprequests: QueryGrouprequestsOverloadI = async ( variables: ListGrouprequestsQueryVariables, limit: number = Infinity, returnPartion: true | false = false ) => { // 原有逻辑 }添加空值检查
在访问res.listGrouprequests前做空值判断,避免运行时错误并修正类型推断:let res = await queryFunction<ListGrouprequestsQueryVariables, ListGrouprequestsQuery>(listGrouprequests, variables) if (!res.listGrouprequests) { // 根据业务需求返回默认值,比如空数组或空连接对象 return returnPartion ? { __typename: "ModelGrouprequestConnection", items: [], nextToken: null } : [] } // 后续使用res.listGrouprequests的逻辑非空断言(可选,需确保类型安全)
若能保证res.listGrouprequests一定存在,可使用非空断言告诉编译器:const connection = res.listGrouprequests!; // 非空断言 if (returnPartion) return connection let result = [...connection.items] // 原有逻辑
内容的提问来源于stack exchange,提问作者Ilijanovic

