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

如何让TypeScript工厂函数根据入参自动收窄返回值类型?

解决TypeScript工厂函数根据brand收窄返回类型的问题

你的问题核心在于原函数的参数类型无法让TypeScript建立brand与对应车型的关联关系,导致返回值无法自动收窄到具体的Car子类型。下面是具体的解决思路和修改后的代码:

解决方案步骤

  • 定义品牌到车型的映射类型,明确每个brand对应的具体Car子类型,让TypeScript能通过brand直接定位到目标类型
  • 使用泛型约束函数的入参和返回值,将输入的brand与返回的车型类型绑定
  • 调整参数类型,确保传入的overrides只能对应目标车型的可选属性,避免类型不兼容

修改后的完整代码

type ToyotaCar = {
  brand: 'toyota'
  isCool: true
}

type LamboCar = {
  brand: 'lambo'
  isAwesome: false
}

type FordCar = {
  brand: 'ford'
  isFast: false
}

// 定义品牌到车型的映射类型,核心关联逻辑
type CarBrandMap = {
  toyota: ToyotaCar
  lambo: LamboCar
  ford: FordCar
}

type Car = ToyotaCar | LamboCar | FordCar

const mockToyota: ToyotaCar = { brand: 'toyota', isCool: true }
const mockLambo: LamboCar = { brand: 'lambo', isAwesome: false }
const mockFord: FordCar = { brand: 'ford', isFast: false }

// 泛型约束brand为CarBrandMap的键,绑定入参和返回值类型
const carFactory = <B extends keyof CarBrandMap>(
  options: Partial<CarBrandMap[B]> & { brand: B }
): CarBrandMap[B] => {
  const { brand, ...overrides } = options
  switch (brand) {
    case 'toyota':
      return { ...mockToyota, ...overrides } as CarBrandMap[B]
    case 'ford':
      return { ...mockFord, ...overrides } as CarBrandMap[B]
    case 'lambo':
      return { ...mockLambo, ...overrides } as CarBrandMap[B]
    default:
      throw new Error(`不支持的品牌:${brand}`)
  }
}

// 类型推导正常,ford会被识别为FordCar类型
const ford = carFactory({ brand: 'ford' })
ford.isFast // 无类型报错,属性访问正常

// 测试自定义属性场景,TypeScript会自动校验属性合法性
const customToyota = carFactory({ brand: 'toyota', isCool: true })
// 若传入不属于ToyotaCar的属性(如isFast),TypeScript会直接报错

关键说明

  1. CarBrandMap映射类型:这是实现类型联动的核心,它将每个brand字符串与对应的Car子类型一一绑定,让TypeScript能明确识别brand对应的具体类型。
  2. 泛型约束:通过<B extends keyof CarBrandMap>限制传入的brand必须是映射类型中的合法键,同时将参数的overrides类型和返回值类型与B关联,实现了基于输入的类型推导。
  3. 类型断言:函数内部的as CarBrandMap[B]是因为TypeScript在switch分支中无法自动将返回值与泛型B关联,手动断言后即可让类型推导正常工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 20:55:16