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

TypeScript如何定义值类型统一且保留键信息的对象?

解决方案:兼顾键名保留与自动类型推断

问题回顾

我定义了一个以Context对象作为第一个参数的Helper函数类型:

type Helper = (ctx: Context, ...params: any[]) => any;

想创建一个所有值均为Helper类型的对象,但现有方案要么丢失键名信息,要么需要重复标注ctx类型:

const lib = {
  path: (ctx) => ctx.getPath(),
  array: (ctx, ...params) => new MyArray(ctx, params),
};

可行方案

方案1:泛型辅助函数(推荐)

通过泛型函数约束对象属性类型的同时,保留原对象的键名信息:

type Helper = (ctx: Context, ...params: any[]) => any;

function createLib<T extends Record<keyof T, Helper>>(lib: T): T {
  return lib;
}

const lib = createLib({
  path: (ctx) => ctx.getPath(), // ctx自动推断为Context类型
  array: (ctx, ...params) => new MyArray(ctx, params), // 无需手动标注ctx类型
});
  • 核心效果:既确保所有函数符合Helper类型规范,又保留path、array等键名的类型推导,IDE可正常补全属性
  • 最终类型:lib的类型被推导为{ path: Helper; array: Helper }

方案2:satisfies关键字断言(简洁版)

利用TypeScript 4.9+的satisfies关键字,在不改变原对象类型推导的前提下,验证属性类型:

type Helper = (ctx: Context, ...params: any[]) => any;

const lib = {
  path: (ctx) => ctx.getPath(),
  array: (ctx, ...params) => new MyArray(ctx, params),
} as const satisfies Record<keyof typeof lib, Helper>;
  • 核心效果:无需额外辅助函数,直接通过断言完成类型检查,同时完整保留键名信息
  • 注意:as const用于锁定对象的键名和函数类型,避免类型被宽泛化

核心优势

两种方案均实现了:

  • 自动推断每个函数的ctx参数为Context类型,无需重复标注
  • 保留对象的所有键名信息,不会丢失属性的类型提示
  • 严格约束所有函数符合Helper类型定义,提供编译期类型检查

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 04:50:17