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

如何实现TypeScript泛型函数的返回类型中data与error始终为可选类型?

让TypeScript泛型HTTP函数返回可选的data和error属性

要实现你的需求——让internalHttp函数返回对象中的data和error始终为可选属性,同时兼顾类型安全,我们可以通过调整返回类型定义来达成目标。下面是两种实用的解决方案:

方案1:直接定义单一可选属性类型

这种方案最贴合你期望的{data?: Data, error?: Error}结构,直接把返回类型改成包含可选data、error和必选isError的单一类型:

// 替换原有的HttpReturnSuccess、HttpReturnError和HttpReturn定义
export type HttpReturn<TData = unknown, TError = unknown> = {
  data?: TData;
  error?: TError;
  isError: boolean;
};

函数实现不需要修改,因为你当前的返回逻辑已经完全符合这个类型:

export const internalHttp = async <Data = unknown, Payload = unknown, Error = unknown>(
  props: HttpProps<Payload>
): Promise<HttpReturn<Data, Error>> => {
  // 原函数实现保持不变
};

现在当你解构返回值时,data和error会被自动推断为Data | undefined和Error | undefined,可以直接使用可选链调用:

const { data } = await internalHttp<{name: "amed"}>();
console.log(data?.name); // TypeScript不会报错,完美支持可选链

方案2:保留联合类型的类型安全,兼容可选访问

如果你想保留原有联合类型的严格类型约束(即isError为false时data一定存在,isError为true时error一定存在),同时支持直接用可选链访问,其实原有的联合类型已经满足需求——你只需要换一种访问方式即可。

原有的联合类型定义本身就会让data的类型推断为Data | undefined,error为Error | undefined,只是TypeScript会要求你在直接访问data.name前检查isError;但如果你使用可选链data?.name,TypeScript会直接允许这种写法,不需要额外的类型判断。

如果你想让类型定义更直观,可以用Partial工具类型包装联合类型:

// 保留原有的HttpReturnSuccess和HttpReturnError
export interface HttpReturnSuccess<TData = unknown> {
  data: TData;
  error: undefined;
  isError: false;
}

export interface HttpReturnError<TError = unknown> {
  data: undefined;
  error: TError;
  isError: true;
}

// 用Partial包装联合类型,让属性变为可选
export type HttpReturn<TData = unknown, TError = unknown> = Partial<HttpReturnSuccess<TData> & HttpReturnError<TError>> & {
  isError: boolean;
};

为什么原有代码的类型提示不符合预期?

原有的HttpReturn是联合类型,TypeScript会触发判别式类型缩小:当你检查isError为false时,它会确定data一定存在;当isError为true时,error一定存在。但如果你不检查isError直接访问data.name,TypeScript会报错——这是它的类型安全机制在起作用。而你期望的可选链访问,其实和原有类型完全兼容,只需要把data.name改成data?.name即可。

如果你希望完全去掉这种判别式约束,直接让data和error成为可选属性,方案1是最直接的选择。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 16:44:04