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

如何移除postEntity函数中的void返回类型并替换为never?

如何移除postEntity函数中的void返回类型并替换为never?

我明白你的问题啦——你希望在循环调用支持post的实体时,postEntity的返回类型里不要混入void,要么把它替换成never,要么直接让不支持post的实体无法传入这个函数。下面给你两种可行的解决思路:

方案一:直接定义支持post的实体子集类型

这个方法最简洁,核心是让类型系统明确知道哪些实体真正支持post,从根源上排除不支持的实体(比如Job)。

首先,把支持post的实体数组改成只读常量,这样TypeScript能精准推导它的类型:

const entityEndpointsSupportingPost = [Entity.Person, Entity.Organization] as const;

然后调整EntityEndpointsSupportingPost,只保留支持post的实体对应的返回类型:

interface Person {}
interface Organization {}

enum Entity {
  Person,
  Organization,
  Job,
}

type EntityEndpointsSupportingPost = {
  [Entity.Person]: Person;
  [Entity.Organization]: Organization;
};

接着从数组推导支持post的实体类型:

type SupportedPostEntity = typeof entityEndpointsSupportingPost[number];

最后修改postEntity的泛型约束,只接受支持post的实体:

async function postEntity<T extends SupportedPostEntity>(endpoint: T): Promise<EntityEndpointsSupportingPost[T]> {
  const result = await fetch(`api/${endpoint}`);
  return await result.json();
}

这样一来:

  • 单独调用postEntity(Entity.Person)时,返回类型还是Promise<Person>,完全没问题;
  • 循环entityEndpointsSupportingPost时,entity的类型会被推断为Entity.Person | Entity.Organization,postEntity(entity)的返回类型就是Promise<Person | Organization>,再也不会出现void了。

方案二:保留原有类型结构,用条件类型替换void为never

如果你需要保留EntityEndpointsSupportingPost的完整结构(比如要明确标记Job不支持post),可以用条件类型把void替换成never,同时限制函数只接受返回类型不是never的实体。

首先定义一个工具类型,把void替换为never:

type NonVoidPostReturn<T extends keyof EntityEndpointsSupportingPost> = 
  EntityEndpointsSupportingPost[T] extends void ? never : EntityEndpointsSupportingPost[T];

然后筛选出支持post的实体类型(排除返回类型为never的实体):

type SupportedPostEntity = Exclude<keyof EntityEndpointsSupportingPost, {
  [K in keyof EntityEndpointsSupportingPost]: NonVoidPostReturn<K> extends never ? K : never
}[keyof EntityEndpointsSupportingPost]>;

最后修改postEntity函数:

async function postEntity<T extends SupportedPostEntity>(endpoint: T): Promise<NonVoidPostReturn<T>> {
  const result = await fetch(`api/${endpoint}`);
  // 这里需要类型断言,因为JSON.parse返回的是unknown,TypeScript无法自动推导到具体类型
  return await result.json() as NonVoidPostReturn<T>;
}

这个方案下:

  • 如果你尝试传入Entity.Job,TypeScript会直接报错,因为它不在SupportedPostEntity范围内;
  • 循环支持post的实体时,返回类型同样不会包含void,完美符合你的需求。

为什么原来的代码会出现void?

简单来说,你原来的postEntity泛型约束是keyof EntityEndpointsSupportingPost,这个类型包含了Entity.Job,所以返回类型自然会带上void。而循环的数组entityEndpointsSupportingPost默认被推断为Entity[],不是精准的子集类型,所以TypeScript会认为你可能传入任何实体,导致返回类型出现void | Person | Organization。上面两个方案都是通过缩小类型范围来解决这个问题的。

备注:内容来源于stack exchange,提问作者tobias47n9e

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.22 08:43:00