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

如何为返回0到n数组的函数定义静态类型

实现返回静态已知类型的0到n数字数组函数

想要实现一个返回从0到n的数字数组的函数,同时希望该函数的返回值具备静态已知的数组类型。示例代码如下:

const makeFoo = (n: number) => [...Array(n).keys()];
const foo1 = [0, 1, 2] as const; // readonly [0, 1, 2]
const foo2 = makeFoo(3); // number[]
console.log(foo1); // [0, 1, 2]
console.log(foo2); // [0, 1, 2]

尽管foo1和foo2在运行时的值相同,但它们的类型不同。请问如何定义makeFoo的返回类型,使其与foo1类似(即readonly [0, 1, ... n],其中n在静态层面也是已知的,例如通过makeFoo = <T extends number>(n: T) => ...这样的泛型方式)?


解决方案

要实现这个需求,需要结合TypeScript的字面量类型、递归条件类型和类型断言,让函数能根据输入的字面量数字n,推导出精确的只读数组类型。

1. 定义递归生成数字序列的类型

先创建一个递归类型,用来生成从0到T-1的数字元组:

type NumberSequence<T extends number, U extends number[] = []> = 
  U['length'] extends T ? U : NumberSequence<T, [...U, U['length']]>;

这个类型的逻辑是:不断往数组U中添加当前数组的长度值,直到U的长度等于输入的T,此时U就是从0到T-1的数字元组。

2. 改造makeFoo函数

利用上面的类型,结合泛型约束和类型断言,改造函数:

const makeFoo = <T extends number>(n: T): Readonly<NumberSequence<T>> => {
  return [...Array(n).keys()] as Readonly<NumberSequence<T>>;
};

3. 测试效果

调用时传入字面量数字,TypeScript就能推导出精确的只读数组类型:

const foo2 = makeFoo(3); // readonly [0, 1, 2]
const foo3 = makeFoo(5); // readonly [0, 1, 2, 3, 4]

注意事项

  • 该方案仅支持字面量数字作为输入,如果传入动态计算的number类型变量,TypeScript无法推导出精确的元组类型,会退化为readonly number[]。
  • TypeScript对递归类型有深度限制,一般支持到约1000左右的数字,超过这个范围可能会触发类型计算报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 13:25:03