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

如何为TypeScript的carryOver函数添加类型,让输出包含输入和返回对象属性?

为carryOver函数添加精确的TypeScript类型定义

原函数实现如下:

carryOver = <T extends Record<string, any>>(fun: (obj: T) => Record<string, any>) => (obj: T) => Object.assign({}, obj, fun(obj))

示例用法:

const makeGreeting = ({name, title}) => ({greeting: `Hello ${title} ${name}`})
const person = {name: "Thomas", title: "Dr."}
const personWithLabel = carryOver(makeGreeting)(person) 
// 期望类型:{ name: string; title: string; greeting: string }

需求是让carryOver的返回值类型同时包含输入对象A的所有属性,以及传入函数返回的新对象B的所有属性。


解决方案:使用双泛型参数与交叉类型

我们可以通过引入第二个泛型参数捕获传入函数返回的对象类型,再通过交叉类型(&)合并输入对象类型和新对象类型,实现精确的类型推导:

const carryOver = <T extends Record<string, unknown>, U extends Record<string, unknown>>(
  fun: (obj: T) => U
) => (obj: T): T & U => Object.assign({}, obj, fun(obj))

类型说明

  • T:表示输入对象的类型,约束为Record<string, unknown>(比any更安全,保留类型检查能力)
  • U:表示传入函数fun返回的新对象的类型,同样约束为字符串键的对象类型
  • 返回值类型T & U:直接合并输入对象和新对象的所有属性,TypeScript会自动推导两者的完整属性集合

验证示例

用原示例测试,TypeScript会自动正确推导类型:

const makeGreeting = ({name, title}: {name: string; title: string}) => ({
  greeting: `Hello ${title} ${name}`
})
const person = {name: "Thomas", title: "Dr."}
const personWithLabel = carryOver(makeGreeting)(person)

// 此时personWithLabel的类型被正确推导为:
// { name: string; title: string; greeting: string }
// 访问personWithLabel.greeting时会有完整的类型提示

即使省略makeGreeting的参数类型,TypeScript依然能通过person的类型反向推导T,进而得到U的类型,最终合并出正确的返回类型。


内容的提问来源于stack exchange,提问作者Adam B.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 15:11:12