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

如何根据传入字符串获取TypeScript函数返回的对应联合类型?

问题描述

给定以下TypeScript函数:

function fetchX(url:string){ 
  switch(url){ 
    case '/api/user': return {name:"Jack"} // User type 
    case '/api/money': return {amonth:100} // Money type 
  } 
}

调用fetchX时,传入不同URL会返回User | Money联合类型,但typeof只能判断原始类型,无法区分这两个对象类型,如何根据传入的字符串获取对应的正确类型?


解决方案

方案一:字符串字面量类型 + 函数重载

先明确定义返回值类型,再给函数添加重载声明,让TypeScript根据传入的URL字面量直接推断返回类型:

// 先定义具体类型
type User = { name: string };
type Money = { amonth: number };

// 函数重载:指定不同URL对应的返回类型
function fetchX(url: '/api/user'): User;
function fetchX(url: '/api/money'): Money;
// 原函数实现
function fetchX(url: string) { 
  switch(url){ 
    case '/api/user': return {name:"Jack"};
    case '/api/money': return {amonth:100};
  } 
}

调用时类型会自动推导:

const user = fetchX('/api/user'); // 类型为User,可直接访问user.name
const money = fetchX('/api/money'); // 类型为Money,可直接访问money.amonth

这种方式完全依赖TS类型系统,不需要运行时判断,适合URL是固定字面量的场景。

方案二:自定义类型守卫(运行时类型校验)

如果URL是动态生成的(比如来自变量),需要在运行时确认类型,可以写自定义类型守卫函数:

type User = { name: string };
type Money = { amonth: number };

// 自定义类型守卫,判断是否为User类型
function isUser(value: unknown): value is User {
  return typeof value === 'object' && value !== null 
    && 'name' in value 
    && typeof (value as User).name === 'string';
}

// 自定义类型守卫,判断是否为Money类型
function isMoney(value: unknown): value is Money {
  return typeof value === 'object' && value !== null 
    && 'amonth' in value 
    && typeof (value as Money).amonth === 'number';
}

使用时,TS会自动缩小类型范围:

function handleResponse(url: string) {
  const res = fetchX(url);
  if (isUser(res)) {
    // 这里res类型自动变为User
    console.log(res.name);
  } else if (isMoney(res)) {
    // 这里res类型自动变为Money
    console.log(res.amonth);
  }
}

方案三:可区分联合类型(添加类型标签)

给返回值添加一个唯一的标识字段(比如type),让TS能通过该字段自动区分联合类型:

// 给每个类型添加唯一的type标签
type User = { type: 'user'; name: string };
type Money = { type: 'money'; amonth: number };
// 定义可区分联合类型
type ApiResponse = User | Money;

function fetchX(url: string): ApiResponse { 
  switch(url){ 
    case '/api/user': return {type: 'user', name:"Jack"};
    case '/api/money': return {type: 'money', amonth:100};
    default: throw new Error('无效的请求URL');
  } 
}

使用时直接通过type字段判断,TS会自动推断类型:

const res = fetchX('/api/user');
if (res.type === 'user') {
  console.log(res.name); // res类型确定为User
} else {
  console.log(res.amonth); // res类型确定为Money
}

这是TS官方推荐的处理复杂联合类型的方式,兼顾运行时判断和类型安全。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 17:56:27