我正在try 创建一个返回从0到n的数字数组的函数,但我希望返回的类型也是已知的静态array.

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]

虽然foo1foo2在运行时具有相同的值,但它们的类型不同.

如何将makeFoo‘S返回类型定义为类似foo1?(readonly [0, 1, ... n]其中n也是静态已知的,例如makeFoo = <T extends number>(n: T) => ...)

推荐答案

你可以使用一个recursive helper类型,它根据一个generic参数计算返回类型.然而,你需要一个type assertion(我不认为没有办法),因为[...Array(n).keys()]总是被推断为number[].

type MakeFoo<N extends number, R extends any[] = []> = R["length"] extends N
  ? R
  : MakeFoo<N, [...R, R["length"]]>;

function makeFoo<N extends number>(n: N): MakeFoo<N> {
  return [...Array(n).keys()] as MakeFoo<N>
}

const foo3 = makeFoo(3);
//    ^? const foo3: [0, 1, 2]
const foo100 = makeFoo(100);
//    ^? const foo100: [0, 1, 2, 3, 4, 5, 6, 7, ... , 99]

TypeScript Playground


注意:这只适用于最多999个项目.以上的任何值都将解析为any.

const foo1000 = makeFoo(1000);
//              ~~~~~~~~~~~~~
// Type instantiation is excessively deep and possibly infinite.

Typescript相关问答推荐

调用另一个函数的函数的Typescript类型,参数相同

VS代码1.88.0中未出现自动导入建议

带有联合参数的静态大小数组

用泛型类型覆盖父类函数导致类型y中的Property x不能赋给基类型Parent中的相同属性."'''''' "

如何为父类构造函数中的修饰属性赋值?

基于键的值的打字动态类型;种类;

角效用函数的类型推断

如何在深度嵌套的Reaction路由对象中隐藏父级?

如何将定义模型(在Vue 3.4中)用于输入以外的其他用途

在VSCode中显示eslint错误,但在终端中运行eslint命令时不显示?(Vite,React,TypeScript)

如何将TS泛型用于react-hook-form接口?

基元类型按引用传递的解决方法

react 路由不响应参数

可赋值给类型的类型,从不赋值

顶点堆叠的图表条形图未在正确的x轴上显示

在打印脚本中将对象类型转换为数组

有没有什么方法可以使用ProvideState()提供多个削减器作为根减减器

传入类型参数<;T>;变容函数

包含多个不同类构造函数的接口的正确类型?

根据索引将元组拆分为两个块