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

TypeScript结合泛型与联合类型按标识返回对应名称的实现问题

问题原因

你当前的写法中,TypeScript 无法通过传入的isPerson参数值自动将泛型T缩窄到对应的Person或Animal子类型,因此返回值会被推导为LivingBeing["name"]的全量联合类型,达不到你要的类型区分效果。

解决方案1:函数重载(最直观易用)

通过定义不同入参对应的返回值重载签名,TS 会在调用时自动匹配对应的重载规则,推导正确的返回类型:

interface Person {
  name: "Peter" | "Robert";
  age: number;
  isPerson: true
}

interface Animal {
  name: "Jerry" | "Tom";
  age: number;
  isPerson: false
}

type LivingBeing = Person | Animal

// 重载签名:入参为true时返回Person的name类型
function getRandomName(isPerson: true): Person["name"]
// 重载签名:入参为false时返回Animal的name类型
function getRandomName(isPerson: false): Animal["name"]
// 内部实现签名
function getRandomName(isPerson: boolean): LivingBeing["name"] {
  const names = isPerson ? ["Peter", "Robert"] : ["Jerry", "Tom"]
  return names[Math.floor(Math.random() * names.length)];
}

const person = getRandomName(true) // 自动推导为 "Peter" | "Robert"
const animal = getRandomName(false) // 自动推导为 "Jerry" | "Tom"

解决方案2:泛型+条件类型

如果希望保留泛型写法,可以直接通过条件类型关联入参布尔值和返回值的对应关系:

function getRandomName<T extends boolean>(isPerson: T): T extends true ? Person["name"] : Animal["name"] {
  const names = isPerson ? ["Peter", "Robert"] : ["Jerry", "Tom"]
  return names[Math.floor(Math.random() * names.length)] as any
}

两种方案都可以实现调用getRandomName(true)时返回值仅为"Peter" | "Robert"的预期效果。


内容的提问来源于stack exchange,提问作者Max García

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 09:24:02