是的,不管出于什么原因,元组索引都是数字字符串literal types,如"0"
和"1"
,而不是对应的numeric文字类型,如0
和1
.还有number
和index signature,所以keyof ["a", "b"]
等于number | "0" | "1" | ...
.这意味着只要使用keyof
,你就可以分配任何数字.
如果要计算数字文字,可以使用template literal types来计算,至少在TypeScrip 4.8和更高版本中是这样:
type TupleIndices<T extends readonly any[]> =
Extract<keyof T, `${number}`> extends `${infer N extends number}` ? N : never;
首先,通过对可被解析为数字的所有字符串的集合`${number}`
进行过滤,来从完整密钥集合中I Extract
数字字符串文字类型.这就消除了number
本身(它不是字符串)以及"length"
和"slice"
以及其他数组成员.所以我们有"0" | "1" | "2" | ...
个.然后,我使用TypeScrip 4.8中引入的the improved infer
types将这些字符串文字转换为数字文字.
这就给了你这个:
const arr = [1, 2] as const;
type ArrIndices = TupleIndices<typeof arr>;
// type ArrIndices = 0 | 1
type Also = TupleIndices<[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]>;
// type Also = 0 | 1 | 2 | 9 | 3 | 4 | 5 | 6 | 7 | 8
Playground link to code个