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

如何将数组所有可能索引转为数字联合类型?

数组索引转数字联合类型问题解决

问题说明

需要将数组的所有可能索引转换为数字联合类型,但当前实现得到的是字符串联合类型,不符合预期:

期望结果

type VoiceSettings = {
    similarityLevel: 0 | 1 | 2 | 3 | 4 | 5;
    stabilityLevel: 0 | 1 | 2 | 3 | 4;
}

实际结果

type VoiceSettings = {
    similarityLevel: "0" | "1" | "2" | "3" | "4";
    stabilityLevel: "0" | "1" | "2" | "3" | "4";
}

现有代码

const VALUES_MAP = {
  similarityLevel: [0, 15, 30, 50, 75, 90],
  stabilityLevel: [15, 30, 60, 75, 90],
} as const;

type ValuesTypes = keyof typeof VALUES_MAP;

type VoiceSettings = {
  [key in ValuesTypes]: Exclude<keyof (typeof VALUES_MAP)[ValuesTypes], keyof []>;
};

解决方案

问题根源在于keyof获取数组索引时返回的是字符串类型(如"0"、"1"),以下两种方案可将其转换为数字联合类型:

方案一:字符串索引转数字类型

通过模板字面量工具类型将字符串形式的索引转换为数字:

const VALUES_MAP = {
  similarityLevel: [0, 15, 30, 50, 75, 90],
  stabilityLevel: [15, 30, 60, 75, 90],
} as const;

type ValuesTypes = keyof typeof VALUES_MAP;

// 工具类型:将字符串索引转为对应数字
type StringToNumber<T extends string> = T extends `${infer N extends number}` ? N : never;

type VoiceSettings = {
  [key in ValuesTypes]: StringToNumber<Exclude<keyof (typeof VALUES_MAP)[key], keyof []>>;
};

方案二:基于数组长度生成数字范围

直接递归生成从0到数组长度-1的数字联合类型,逻辑更直观:

const VALUES_MAP = {
  similarityLevel: [0, 15, 30, 50, 75, 90],
  stabilityLevel: [15, 30, 60, 75, 90],
} as const;

type ValuesTypes = keyof typeof VALUES_MAP;

// 递归生成0到N-1的数字范围类型
type NumberRange<N extends number, Acc extends number[] = []> = Acc['length'] extends N 
  ? Acc[number] 
  : NumberRange<N, [...Acc, Acc['length']]>;

type VoiceSettings = {
  [key in ValuesTypes]: NumberRange<(typeof VALUES_MAP)[key]['length']>;
};

说明

  • 方案一针对已有的字符串索引做类型转换,适配场景更灵活;
  • 方案二直接基于数组长度生成索引范围,代码更简洁,适合仅需数组合法索引的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 04:45:01