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

TypeScript如何约束数组键类型仅为合法索引且匹配数组长度

keyof typeof arr无法得到预期的索引约束效果,核心原因是TypeScript的数组类型默认带有通用number索引签名,keyof操作会同时返回数组原型方法的键名、通用数字索引类型,不会收敛到数组实际存在的具体索引字面量,因此会放行所有数字类型值。

实现方案

通过递归类型构造从0开始递增的数字序列,最终生成匹配数组长度的合法索引联合类型,仅适用于as const定义的固定长度常量数组、或显式声明的元组类型:

// 递归生成0到目标长度-1的非负整数联合
type BuildIndexes<Length extends number, Result extends number[] = []> = 
  Result['length'] extends Length
    ? Result[number]
    : BuildIndexes<Length, [...Result, Result['length']]>

// 提取目标数组的合法索引类型
const arr = ["a", "b", "c"] as const
type ValidArrIndex = BuildIndexes<typeof arr['length']>

校验结果

let a: ValidArrIndex = 0    // ✔️ 校验通过,属于数组合法索引
let b: ValidArrIndex = 2    // ✔️ 校验通过,属于数组合法索引
let c: ValidArrIndex = -1   // ❌ 类型报错,负数不属于合法索引范围
let d: ValidArrIndex = 999  // ❌ 类型报错,索引超出数组实际长度
限制说明
  • 该方案仅对长度固定的元组生效:如果是普通动态长度数组(例如标注为string[]的数组),其length类型为通用number,静态类型层面无法预知运行时的数组长度,因此不可能实现精确的索引约束。
  • 受TypeScript类型递归深度限制,该方案支持的元组最大长度约为50,覆盖绝大多数常量枚举类场景的使用需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 08:24:16