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

TypeScript中能否定义关联参数与响应的联合类型并复用?

如何在TypeScript中复用ResponseMap实现输入参数到输出类型的精确映射?

你遇到的问题是原有的泛型写法无法让TypeScript精确推断出输入路径对应的响应类型,导致返回类型变成了所有可能响应的联合类型。要复用ResponseMap同时实现精确的类型映射,有两种可行方案:

方案1:将ResponseMap重构为索引类型(推荐)

把原来的联合类型改成键值对形式的索引类型,更符合"路径-响应类型"的映射逻辑,TypeScript也能更轻松地做精确推断:

// 定义索引类型的ResponseMap,路径作为键,响应类型作为值
type ResponseMap = {
  "/user/": UserData;
  "/posts/": PostData;
};

// 泛型约束路径为ResponseMap的键,返回对应的值类型
async function getRequest<Path extends keyof ResponseMap>(
  path: Path
): Promise<ResponseMap[Path] | undefined> {
  const response = await fetch(path);
  return response.json();
}

// 此时类型推断正确,不会报错
const response: UserData | undefined = await getRequest("/user/");

这种方式的优势是直观易懂,而且ResponseMap可以直接在其他函数中复用:

// 复用ResponseMap的POST请求函数
async function postRequest<Path extends keyof ResponseMap>(
  path: Path,
  payload: Partial<ResponseMap[Path]>
): Promise<ResponseMap[Path]> {
  const response = await fetch(path, {
    method: "POST",
    body: JSON.stringify(payload),
    headers: { "Content-Type": "application/json" }
  });
  return response.json();
}

方案2:保留联合类型,用Extract条件类型提取对应项

如果你想保留原来的联合类型结构,可以通过Extract条件类型从ResponseMap中提取对应路径的响应类型:

// 保留原有的联合类型ResponseMap
type ResponseMap =
  { requestPath: "/user/", response: UserData } |
  { requestPath: "/posts/", response: PostData };

// 定义条件类型,根据路径提取对应的响应类型
type ResponseForPath<Path extends ResponseMap["requestPath"]> = 
  Extract<ResponseMap, { requestPath: Path }>["response"];

// 泛型约束路径为ResponseMap中的requestPath,返回提取出的响应类型
async function getRequest<Path extends ResponseMap["requestPath"]>(
  path: Path
): Promise<ResponseForPath<Path> | undefined> {
  const response = await fetch(path);
  return response.json();
}

// 类型推断正确,无报错
const response: UserData | undefined = await getRequest("/user/");

这种方案也能实现类型精确推断,并且ResponseMap同样可以在其他需要路径-响应映射的地方复用。

为什么原代码会报错?

原代码中Value extends ResponseMap的泛型约束,当传入具体路径时,TypeScript无法确定Value是联合类型中的哪一项,因此会将Value["response"]推断为所有可能响应类型的联合(UserData | PostData),导致返回类型和你期望的单一类型不匹配,从而报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 13:05:26