如何将动态类型断言转换为静态类型断言?

How to transform dynamic type assertion to static one?

有没有办法在 中动态生成 const 断言?

我知道你可以创建一个基于静态类型数组的readonlyArray断言,例如

 const staticTyped = [1, 2, 3] as const // readonly [1, 2, 3]
 type TypeStatic = typeof staticTyped[number] // 1 | 2 | 3

现在可以按预期正常工作了。但是,我需要创建一个动态生成的大型只读数组。

const generateNumRange = (from: number, to: number): number[] => {
  const arr = []
  for (let i = from; i <= to; i++) {
     arr.push(i)
  }
  return arr
}

const dynamicTyped = [...generateNumRange(0, 255)] as const // readonly number[]
type TypeDynamic = typeof dynamicTyped[number] // number (oof)

现在我明白问题出在哪里了,但是我想不出一个方法,让我可以 return dyanmicTyped 作为 [0, 1, 2, ..., 255] 而不是 number[].

有没有办法做到这一点/也许更优雅地解决问题?

回想一下,类型系统在运行时并不存在。 https://github.com/microsoft/TypeScript/issues/15480 范围类型请求已久。

我不明白为什么类型 number[] 是不可接受的,但是如果你 绝对 需要推断类型,你将不得不告诉 TS 确切地做什么.

(我以前见过库作者这样做,所以也许它不是那么愚蠢?但希望这说明你已经达到了类型系统的极限之一。)

type T1_2 = 0 | 1 | 2;
type T1_3 = T1_2 | 3;
type T1_4 = T1_3 | 4;

function generateNumRange(from: 0, to: 2): T1_2[];
function generateNumRange(from: 0, to: 3): T1_3[];
function generateNumRange(from: 0, to: 4): T1_4[];
function generateNumRange<T>(from: number, to: number): T[] {
  const arr = []
  for (let i = from; i <= to; i++) {
    arr.push(i)
  }
  return arr
}

const dynamicTyped = [...generateNumRange(0, 3)]
type TypeDynamic = typeof dynamicTyped[number] // 0 | 1 | 2 | 3

const dynamicTyped4 = [...generateNumRange(0, 4)]
type TypeDynamic4 = typeof dynamicTyped4[number] // 0 | 1 | 2 | 3 | 4

希望你能看到你可以在一个简单的 for 循环中生成所有这些代码,最多可以生成你想要的任何有限数字。