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

如何让TypeScript自动推导元组参数类型 无需as const实现Lodash at类函数

解决方案

可以实现,核心是利用TypeScript 5.0引入的const泛型修饰符,让编译器自动把传入的路径数组推导为字面量元组,无需用户手动加as const。

修改后的完整代码

仅需要调整函数的泛型声明,原有路径匹配的类型逻辑不需要改动:

type PropertyAtPath<T, Path extends readonly any[]> = Path extends []
  ? T
  : Path extends readonly [infer First, ...infer Rest]
  ? First extends keyof T
    ? PropertyAtPath<T[First], Rest>
    : undefined
  : unknown;

type At<T, Paths extends ReadonlyArray<ReadonlyArray<any>>> = {
  [I in keyof Paths]: Paths[I] extends readonly any[]
    ? PropertyAtPath<T, Paths[I]>
    : never;
};

// 仅在泛型Paths前加const修饰符即可
declare function at<T, const Paths extends ReadonlyArray<ReadonlyArray<any>>>(
  object: T,
  ...paths: Paths
): At<T, Paths>;

效果验证

const obj = {
  key1: '字符串值',
  key2: {
    key3: 1234
  }
};

// 无需加as const,直接调用即可正确推导类型
const result = at(obj, ['key1'], ['key2', 'key3']);
// result的类型自动推导为:[string, number]

原理解释

  • 默认情况下TypeScript会把传入的数组字面量推导为可变的普通数组类型(比如['key1']会被推导为string[]),无法匹配路径需要的字面量元组类型,所以原来的实现必须要用户手动加as const把数组转为只读字面量元组。
  • TypeScript 5.0新增的const泛型修饰符,作用就是让编译器在推导泛型参数类型时,直接按照字面量常量的规则推导,效果等价于用户在所有入参前加了as const,无需修改调用侧代码。

低版本TS兼容方案

如果你的项目TS版本低于5.0,可以通过写函数重载的方式支持有限个数的路径参数,无需const修饰符:

// 重载1:支持1个路径
declare function at<T, P1 extends readonly PropertyKey[]>(obj: T, path1: P1): [PropertyAtPath<T, P1>]
// 重载2:支持2个路径
declare function at<T, P1 extends readonly PropertyKey[], P2 extends readonly PropertyKey[]>(obj: T, path1: P1, path2: P2): [PropertyAtPath<T, P1>, PropertyAtPath<T, P2>]
// 可根据业务需要继续扩展更多重载,支持更多路径参数

这种方案的缺点是需要手动写重载覆盖你需要支持的最大路径个数,无法支持任意个数的路径参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 03:48:03