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

如何根据Class类型参数确定TypeScript函数的返回类型?

解决TypeScript中基于类实例参数的返回类型推断问题

你的问题根源在于TypeScript的结构类型系统:空类Foo和Bar的实例结构完全一致(都没有任何属性/方法),所以TypeScript会将它们视为可兼容的类型,导致你的条件类型和重载写法都无法正确区分两者。

下面是几种可行的解决方案:

方案1:给类添加标志性属性(最直观)

通过给每个类添加唯一的字面量属性,让TypeScript能通过结构区分它们:

class Foo {
  readonly type: 'Foo' = 'Foo'
}
class Bar {
  readonly type: 'Bar' = 'Bar'
}

function update<T extends Foo | Bar>(item: T): T['type'] {
  return item.type as T['type']
}

// 测试
const foo = new Foo()
const bar = new Bar()

const result1 = update(foo) // 类型:"Foo"
const result2 = update(bar) // 类型:"Bar"

方案2:利用私有属性实现名义类型

如果不想暴露额外属性,可以用私有属性让TypeScript将两个类视为不同类型(私有属性的兼容性检查基于类本身而非结构):

class Foo {
  private readonly _brand: void
}
class Bar {
  private readonly _brand: void
}

function update<T extends Foo | Bar>(item: T): T extends Foo ? 'Foo' : 'Bar' {
  return (item instanceof Foo ? 'Foo' : 'Bar') as T extends Foo ? 'Foo' : 'Bar'
}

// 测试
const foo = new Foo()
const bar = new Bar()

const result1 = update(foo) // 类型:"Foo"
const result2 = update(bar) // 类型:"Bar"

方案3:正确编写重载并配合类型收窄

如果坚持使用重载,需要在函数体内通过instanceof做类型收窄,同时确保TypeScript能正确匹配重载分支:

class Foo {}
class Bar {}

function update(item: Foo): 'Foo';
function update(item: Bar): 'Bar';
function update(item: Foo | Bar): 'Foo' | 'Bar' {
  if (item instanceof Foo) {
    return 'Foo' as const
  }
  return 'Bar' as const
}

// 测试
const foo = new Foo()
const bar = new Bar()

const result1 = update(foo) // 类型:"Foo"
const result2 = update(bar) // 类型:"Bar"

这里的关键是用instanceof基于原型链判断实例类型,同时返回字面量类型(as const确保返回值是具体的字符串字面量而非string),让TypeScript能正确关联重载的参数和返回类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 08:50:23