【问题标题】:How to create a union type of indexes of a constant array with Typescript?如何使用 Typescript 创建常量数组的联合类型索引?
【发布时间】:2021-06-21 11:04:17
【问题描述】:

我有一个常量字符串数组,例如

const emojis = ['????', '????', '????', '????', '????'] as const

我想要一个包含该数组索引联合的类型,例如

type emojiIndexes = IndexesOfArray<typeof emojis> // => 0 | 1 | 2 | 3 | 4

所以我不允许使用 number 并且只使用数组中索引的确切数量

如果数组大小例如

// changed from this
// const emojis = ['????', '????', '????', '????', '????'] as const
// to this 
const emojis = ['????', '????', '????'] as const // removed 2 emojis

比,IndexesOfArray&lt;typeof emojis&gt; 将是 0 | 1 | 2

我如何创建IndexesOfArray 来创建具有常量数组索引的联合类型?

【问题讨论】:

    标签: typescript typescript-generics


    【解决方案1】:

    您可以通过从参数类型中排除所有空数组键来做到这一点,因此您最终得到的只是索引的联合:

    type IndexesOfArray<A> = Exclude<keyof A, keyof []>
    
    const emojis = ['?', '?', '?', '?', '?'] as const
    
    type emojiIndexes = IndexesOfArray<typeof emojis> // => '0' | '1' | '2' | '3' | '4'
    

    索引是字符串而不是数字,但这不会导致任何问题。如果确实需要数字,可以使用递归条件类型来生成它们,但这会导致 TypeScript 的递归深度出现问题。或者,您可以使用稍微有点 hacky 的硬编码数组和索引来获取数字:

    type ToNum = [0,1,2,3,4,5,6,7] // add as many as necessary
    
    type emojiNumIndexes = ToNum[IndexesOfArray<typeof emojis>] // => 0 | 1 | 2 | 3 | 4
    

    TypeScript playground

    【讨论】:

    • 完美!但是有可能把它变成数字吗? keyof A 是字符串
    • 啊,是的,刚刚写了一行。我不认为你可以轻易得到数字。让我看看。
    【解决方案2】:

    这是一个解决方案:

    type TupleIndices<A extends any[]>
        = A extends [any, ...infer T]
        ? TupleIndices<T> | T['length']
        : never
    

    例子:

    type Foo = ['foo', 'bar', 'baz', 'qux', 'quz']
    
    // 0 | 4 | 3 | 2 | 1
    type FooIndices = TupleIndices<Foo>
    

    Playground Link

    【讨论】:

    • 由于递归限制,这在超过 23 个元素上失败。
    • @Oblosys 是的,这很可能,但我怀疑还有什么更好的——至少在 Typescript 引入对数字范围类型的支持之前(请参阅this suggestion on the issue tracker)。一般来说,你不能在编译时使用 Typescript 的类型系统来做“太多”的计算。
    • 没错,我通常只是使用字符串的并集,到目前为止还没有任何问题。
    猜你喜欢
    • 1970-01-01
    • 2021-09-27
    • 1970-01-01
    • 1970-01-01
    • 2022-12-18
    • 1970-01-01
    • 1970-01-01
    • 2016-11-03
    相关资源
    最近更新 更多