TypeScript条件类型报错:类型无法分配给条件类型
解决TypeScript条件类型函数返回值不匹配问题
问题原因
TypeScript编译器无法在函数内部跟踪泛型T的具体类型分支。虽然你通过if(type === 'saved')明确了当前分支的输入类型,但编译器没办法将这个条件判断和泛型T的约束关联起来,因此认为返回的string[]或ProductType[]无法匹配QueryResponse<T>的泛型类型。
另外你代码里存在笔误:ProductExample[]应该改为ProductType[],否则会报“找不到名称ProductExample”的错误。
解决方案
方案一:类型断言(快速解决)
直接在return语句中使用类型断言,明确告诉编译器当前返回值就是QueryResponse<T>的正确类型:
type ProductType = { title: string; price: number; }; type QueryResponse<T> = T extends 'unsaved' ? ProductType[] : T extends 'saved' ? string[] : never; export async function queryDb<T extends 'saved' | 'unsaved'>( type: T, ): Promise<QueryResponse<T>> { let dbUrl: string; if (type === 'saved') { dbUrl = 'DATABASEURL/saved'; } else { dbUrl = 'DATABASEURL/unsaved'; } const r = await fetch(dbUrl); const dbResult = JSON.parse(await r.json()); if (type === 'saved') { let response: string[] = dbResult.data; return response as QueryResponse<T>; // 添加类型断言 } else { let response: ProductType[] = dbResult.data; // 修正笔误 return response as QueryResponse<T>; // 添加类型断言 } }
方案二:函数重载(类型更安全)
使用函数重载明确每个输入类型对应的返回类型,这种方式无需泛型,类型推断逻辑更清晰:
type ProductType = { title: string; price: number; }; // 重载签名:定义输入与输出的对应关系 export async function queryDb(type: 'saved'): Promise<string[]>; export async function queryDb(type: 'unsaved'): Promise<ProductType[]>; // 函数实现:使用联合类型接收参数 export async function queryDb(type: 'saved' | 'unsaved') { let dbUrl: string; if (type === 'saved') { dbUrl = 'DATABASEURL/saved'; } else { dbUrl = 'DATABASEURL/unsaved'; } const r = await fetch(dbUrl); const dbResult = JSON.parse(await r.json()); if (type === 'saved') { return dbResult.data as string[]; } else { return dbResult.data as ProductType[]; } }
调用时TypeScript会自动根据传入的type推断返回值类型:
// 返回值类型为Promise<string[]> queryDb('saved'); // 返回值类型为Promise<ProductType[]> queryDb('unsaved');
内容的提问来源于stack exchange,提问作者bourkison
相关产品推荐
相关产品推荐

