如何定义接收、返回带任意数量键对象的TypeScript函数?
TypeScript 任意对象入参/返回值的函数类型最佳实践
你当前使用的const myFunc: ({}) => ({})写法存在明显缺陷:{}在TS中是空对象类型,不仅会允许数字、字符串等原始类型作为参数传入(原始类型可隐式转为对象),而且后续访问返回值的任意属性都会触发类型报错,完全无法发挥TS的类型优势。
下面是两种更合理的实现方案,可根据业务场景选择:
方案1:仅约束输入输出为对象,不需要保留具体属性类型
如果不需要TS推导和保留输入、返回对象的具体属性信息,只需要强约束必须传入对象、返回对象,可以使用Record类型定义:
// 键仅为字符串的对象 const myFunc: (input: Record<string, unknown>) => Record<string, unknown> = (input) => { // 业务逻辑 return {} } // 覆盖字符串、数字、Symbol所有合法键类型的对象 const myFunc: (input: Record<PropertyKey, unknown>) => Record<PropertyKey, unknown> = (input) => { // 业务逻辑 return {} }
该方案的优势:
- 严格拦截非对象类型的入参,避免隐式类型转换的坑
unknown类型保证你不会随意操作对象属性,要操作属性必须先做类型收窄,符合类型安全要求- 写法简单,适合不需要感知对象具体结构的通用工具类函数
方案2:保留输入输出的属性类型,最大化利用TS类型能力
如果希望输入对象的属性类型可以被TS自动推导,返回对象的类型也可以对应保留属性提示,使用泛型实现是最优解:
// 入参和返回值类型一致的场景 const myFunc = <T extends Record<PropertyKey, unknown>>(input: T): T => { // 比如对入参做修改后返回 input.count = input.count + 1 return input } // 返回值在入参基础上新增属性的场景 const addExtraProp = <T extends Record<PropertyKey, unknown>>(input: T): T & { extra: string } => { return { ...input, extra: '附加属性' } }
该方案的优势:
- 调用函数时TS会自动推断入参的所有属性类型,返回值也会对应保留完整的类型信息
- 后续使用返回值时可以获得完整的属性补全、类型校验,完全发挥TS的类型优势
- 灵活度高,可根据业务需要自定义返回值和入参的类型关联关系
避坑提醒
不要使用object或者any作为类型定义:
object类型虽然能约束为对象,但无法访问、修改任何属性,使用限制极大any会完全关闭类型校验,等于放弃TS的类型能力,非常不推荐使用
内容的提问来源于stack exchange,提问作者internet
相关产品推荐
相关产品推荐

