如何根据传入字符串获取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
相关产品推荐
相关产品推荐

