如何在AWS Amplify Gen 2中预加载关联模型且避免TypeScript错误
如何在AWS Amplify Gen 2中预加载关联模型且避免TypeScript错误
我来帮你搞定这个问题!首先得搞明白为啥会出这个TypeScript错误:Amplify Gen2的模型里,belongsTo关联默认是LazyLoader类型(一个延迟加载的函数),而你预加载后把这个函数替换成了实际的DataType对象/undefined,这就和原来的类型定义直接冲突了——TS会认为你同时需要这个字段既是LazyLoader函数,又是实际的数据对象,当然会报错。
问题根源拆解
你之前的两次尝试都踩了同一个坑:用交叉类型(&)去扩展原模型类型,这会保留原来的dataType: LazyLoader<...>定义,同时又要求它是实际的DataType对象,这两个类型是互斥的,所以TS直接给你抛出了类型不兼容的错误。
正确的解决方案
我们需要完全替换掉原类型中dataType的定义,而不是交叉扩展。步骤如下:
1. 定义预加载后的新类型
先移除原DataCategory类型里的dataType字段(它是LazyLoader类型),再重新定义为实际的DataType对象或null/undefined:
// 从Schema中获取原始的模型类型 type OriginalDataCategory = Schema["DataCategory"]["type"]; type ResolvedDataType = Schema["DataType"]["type"]; // 定义预加载后的DataCategory类型:替换dataType为实际的DataType type ResolvedDataCategory = Omit<OriginalDataCategory, "dataType"> & { dataType?: ResolvedDataType | null; };
2. 修正订阅函数的类型与逻辑
把订阅函数的callback参数类型换成我们新定义的ResolvedDataCategory[],同时简化预加载的逻辑(await item.dataType()直接返回DataType | null,不需要额外取.data):
export function subscribeToDataCategories( callback: (items: ResolvedDataCategory[]) => void ): () => void { const sub = client.models.DataCategory.observeQuery().subscribe({ next: async (result: { items?: OriginalDataCategory[] }) => { console.log("Updating DataCategories:", result.items); if (!result.items) { callback([]); return; } const enrichedItems = await Promise.all( result.items.map(async (item) => { try { // 直接await LazyLoader函数,获取实际的DataType | null const dataType = await item.dataType(); // 用新类型断言,确保TS识别正确 return { ...item, dataType } as ResolvedDataCategory; } catch (error) { console.error( `Failed to fetch DataType for ID ${item.dataTypeId}:`, error ); // 加载失败时,保留dataType为undefined return { ...item, dataType: undefined } as ResolvedDataCategory; } }) ); console.log("Enriched Categories:", enrichedItems); callback(enrichedItems); }, error: (error: unknown) => { console.error("Subscription error:", error); }, }); return () => sub.unsubscribe(); }
3. 为什么这个方案能解决问题?
- 我们用
Omit<OriginalDataCategory, "dataType">彻底移除了原类型中dataType的LazyLoader定义,避免了类型冲突 - 新的
dataType类型明确是实际的模型对象或空值,和预加载后的实际值完全匹配 - 类型断言
as ResolvedDataCategory帮助TS正确推导返回值的类型
对你之前尝试的小总结
- Attempt1:你定义的
ResolvedDataType里还保留了嵌套的LazyLoader(比如dataCategories),这本身没问题,但核心错误是EnrichedDataCategory用了交叉类型,没有完全替换掉原dataType的LazyLoader定义,导致TS要求字段同时满足两种互斥的类型 - Attempt2:同样是交叉类型的问题,原
dataType是LazyLoader,交叉后要求它既是LazyLoader又是DataType | undefined,自然会报错
备注:内容来源于stack exchange,提问作者e_aman
相关产品推荐
相关产品推荐

