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

TypeScript中如何从动态数组生成字符串字面量类型

问题原理

TypeScript 类型系统完全在编译阶段执行,无法感知运行时Array.from生成数组的具体长度,你写的ReadonlyArray<number>类型本身不携带固定长度的字面量信息,因此keyof A只能拿到通用number类型,推导出来的ScaleKeys只会是${number}x,无法得到具体的索引字符串字面量联合。

该需求可以通过提前指定长度泛型的方案实现,同时满足运行时动态生成数组、编译时自动生成目标字面量类型的要求,不需要手动声明长静态数组。

实现代码
// 类型工具:生成 0 ~ L-1 的数字联合类型
type NumRange<L extends number, Temp extends number[] = []> = 
  Temp['length'] extends L 
    ? Temp[number] 
    : NumRange<L, [...Temp, Temp['length']]>;

// 类型工具:根据数组长度直接生成目标 `${数字}x` 联合类型
type ScaleKeysByLength<L extends number> = `${NumRange<L>}x`;

// 运行时工具:生成指定长度的数组,同时绑定长度类型
function createScaleArray<L extends number>(
  length: L,
  fillCallback: (index: number) => number = (i) => i
): readonly number[] & { length: L } {
  return Array.from({ length }, (_, idx) => fillCallback(idx)) as const;
}
使用示例
// 生成长度为20、值为0/0.5/1/.../9.5的数组,和你原来的步长规则对齐
const spacing = createScaleArray(20, i => i * 0.5);
// 直接生成长度20对应的索引字符串联合类型
type SpaceKeys = ScaleKeysByLength<20>;

// 类型校验测试
const validKey1: SpaceKeys = '0x'; // 正常通过
const validKey2: SpaceKeys = '19x'; // 正常通过
const invalidKey: SpaceKeys = '20x'; // 编译报错,超出索引范围

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 12:54:03