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

Supabase查询中条件类型引发TypeScript 'never'类型赋值错误

问题根源:DbResultOk 类型定义与使用不匹配

问题原因分析

你定义的DbResultOk<T>类型逻辑是仅当传入的T是包含data字段的PromiseLike类型时,才提取data的类型并排除null值;如果传入的T不是PromiseLike类型,条件判断不成立,类型就会回退为never。

现在你在代码中直接传入了Tables<"FuenteIngreso">[](这是一个数组类型,而非Promise),导致T extends PromiseLike<{ data: infer U }>的条件不满足,DbResultOk<T>最终解析为never,自然触发了类型不匹配的报错。

同时你的辅助类型设计存在逻辑偏差:DbResultOk的初衷应该是从Supabase查询的Promise结果中提取成功的data类型,但当前定义要求输入必须是Promise,你却直接传入了最终的data类型(数组),完全偏离了类型的设计意图。

修正方案

方案1:调整DbResultOk定义,支持多场景使用

修改类型定义,让它既能处理Promise类型,也能直接处理数据/结果对象类型:

// 通用逻辑:提取data字段并排除null
type ExtractNonNullData<T> = T extends { data: infer U }
  ? Exclude<U, null>
  : Exclude<T, null>;

// 处理Promise或直接传入的类型
export type DbResultOk<T> = T extends PromiseLike<infer U>
  ? ExtractNonNullData<U>
  : ExtractNonNullData<T>;

方案2:按原设计正确使用DbResultOk

如果不想修改类型定义,应该传入查询的Promise类型(typeof query)来获取正确的data类型,而非直接传入数组:

export async function addFrequentIngresoAccion(payload: {
  // ... payload definition
}): Promise<DbResult<any>> {
  const supabase = createServerActionClient<Database>({ cookies });
  const query = supabase.from("FuenteIngreso").insert([/*...*/]).select();
  const result: DbResult<typeof query> = await query;

  if (result.error) {
    const resultErr: DbResultErr = result.error;
    return { error: resultErr };
  }

  // 正确传入Promise类型获取data类型
  type FuenteIngresoData = DbResultOk<typeof query>;
  const resultOk: FuenteIngresoData = result.data as FuenteIngresoData;
  return { data: resultOk };
}

优化函数返回类型

另外,函数返回类型Promise<DbResult<any>>过于宽泛,建议明确返回类型以获得更好的类型提示:

// 定义明确的返回类型
type AddFrequentIngresoResult =
  | { data: DbResultOk<typeof query> }
  | { error: DbResultErr };

export async function addFrequentIngresoAccion(payload: {
  // ... payload definition
}): Promise<AddFrequentIngresoResult> {
  const supabase = createServerActionClient<Database>({ cookies });
  const query = supabase.from("FuenteIngreso").insert([/*...*/]).select();
  const result = await query;

  if (result.error) {
    return { error: result.error };
  }

  const resultOk = result.data as DbResultOk<typeof query>;
  return { data: resultOk };
}

额外提示

  • DbResult<T>的定义是合理的,但应避免在返回类型中使用DbResult<any>,否则会失去TypeScript的类型校验意义。
  • Supabase自动生成的Database类型已经包含了查询返回的精确类型,你可以直接基于它来定义类型,无需完全自定义辅助类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 04:03:32