在TypeScript中双展开嵌套的可变参数元组

dx_over_dt

tl; dr:我要强烈键入以下内容。

const foo = [ 'a' ] as const;
const bar = [ 1 ] as const;
const baz = [ true ] as const;

const concatted = foo.concat(bar, baz);

type Concatted = typeof concatted; // expect ['a', 1, true]

我已经想出了如何为0..n参数添加定义,但是我想对任意数量的对象进行添加,最好使用一个或两个定义。


假设我有:

const strArray = [ 'a' ] as const;
const numArray = [ 1 ] as const;

const concatenated = strArray.concat(numArray);

我们知道级联等于['a', 1]我已经弄清楚了如何为此编写类型定义concat()

declare global {
    interface ReadonlyArray<T> {
        concat<
            A extends ReadonlyArray<T>, 
            I extends ReadonlyArray<unknown>
        >(this: A, items: C): [...A, ...I];
    }
}

type Concatenated = typeof concatenated; // => ['a', 1]

但是,JavaScriptArray.concat()接受任意数量的数组。所以现在开始

const strArray = [ 'a' ] as const;
const numArray = [ 1 ] as const;
const boolArray = [ true ] as const;

const concatenated = strArray.concat(numArray, boolArray); // => [ 'a', 1, true ]

在TypeScript 4的可变参数元组之前,解决方案类似于

declare global {
    interface ReadonlyArray<T> {
        concat<
            A extends ReadonlyArray<T>, 
            I extends ReadonlyArray<unknown>
        >(this: A, items: I): [...A, ...I];
        concat<
            A extends ReadonlyArray<T>,
            I1 extends ReadonlyArray<unknown>, 
            I2 extends ReadonlyArray<unknown>
        >(this: A, item1: I1, item2: I2): [...A, ...I1, ...I2];
        // ...additional concat() definitions through I_n...
    }
}

我希望有了TypeScript 4,我可以做些更简单的事情

declare global {
    interface ReadonlyArray<T> {
        concat<
            A extends ReadonlyArray<T>, 
            I extends ReadonlyArray<ReadonlyArray<unknown>>
        >(this: A, ...items: I): [...A, ...(...I)];
    }
}

这显然行不通。我猜有一些黑魔法使用

((val: ReadonlyArray<ReadonlyArray<unknown>>) => void) extends ((val: [infer U, ...infer R]) => void)
    ? [...U, ...<something something recurse with R>] 
    : never

模式,我从来没有使用得到的窍门,也许在串联与魔法Extract<>所看到的这个答案

如果类型可以在没有任何魔术的情况下进行递归,那将非常好。然后我可以轻松地写:

type Concat<T extends ReadonlyArray<ReadonlyArray<unknown>>> = 
    T extends [ReadonlyArray<unknown>, ...infer U]
        ? [...T[0], ...Concat<U>]
        : [];

interface ReadonlyArray<T> {
    concat<
        A extends ReadonlyArray<T>, 
        I extends ReadonlyArray<ReadonlyArray<unknown>>
    >(this: A, ...items: I): [...A, ...Concat<I>];
}

TypeScript游乐场

顺便说一句,我从来不理解为什么不支持递归类型(只要它们在n个深度之内即可解析)。无限递归当然是不好的/不可能的,但是我认为可以很容易/有效地为大小为100或小于100的元组支持此语法。

Aleksey L.

在Typescript 4.1中将添加递归条件类型的官方支持。
有了它,我们将能够:

type Concat<T> = 
    T extends [infer Head, ...infer Tail] 
      ? Head extends ReadonlyArray<unknown> 
        ? [...Concat<Head>, ...Concat<Tail>] : [Head, ...Concat<Tail>]
      : T

上面的定义允许传递数组和/或值以连接到一个新数组中(就像常规的concat一样

操场


递归限制为50个嵌套类型的实例

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在Typescript中包装可变参数元组类型

来自分类Dev

TypeScript:从可变参数元组类型推断数据类型

来自分类Dev

元组的可变参数生成

来自分类Dev

可变参数后元组中的可选函数参数

来自分类Dev

嵌套类中的可变参数模板

来自分类Dev

C ++中的嵌套可变参数函数

来自分类Dev

可变参数模板中的shared_ptr元组?

来自分类Dev

可变参数模板中的shared_ptr元组?

来自分类Dev

TypeScript中的可变长度数组元组?

来自分类Dev

无法创建可变参数元组

来自分类Dev

可变参数嵌套循环

来自分类Dev

从可变参数模板数组引用构造函数初始化双嵌套std :: array

来自分类Dev

C ++ SFINAE双嵌套的initializer_list与可变参数模板构造函数

来自分类Dev

保留参数类型的函数映射数组。TypeScript v4中的可变参数元组类型可以改善这一点吗?

来自分类Dev

如何将TypeScript可变参数元组类型用于笛卡尔积函数?

来自分类Dev

可变参数模板与使用元组在参数中添加不同的数据对

来自分类Dev

将相同的参数转发给C ++中的可变参数元组构造函数

来自分类Dev

tidyverse中的双嵌套

来自分类Dev

“无法创建可变参数元组”错误

来自分类Dev

根据函数的可变参数构建特定的元组

来自分类Dev

在Coq中展开嵌套定义

来自分类Dev

在C中展开嵌套嵌套循环

来自分类Dev

在可变参数模板类的构造函数中初始化元组成员

来自分类Dev

在D中,如何在整个元组上指定可变参数模板约束?

来自分类Dev

TypeScript可变参数元组类型推断问题,针对运行一系列“结果”返回函数的函数

来自分类Dev

可变参数模板展开到std :: tuple

来自分类Dev

可变参数模板展开到std :: tuple

来自分类Dev

宏中的可变参数

来自分类Dev

将可变参数模板参数用于元组失败的向量

Related 相关文章

  1. 1

    在Typescript中包装可变参数元组类型

  2. 2

    TypeScript:从可变参数元组类型推断数据类型

  3. 3

    元组的可变参数生成

  4. 4

    可变参数后元组中的可选函数参数

  5. 5

    嵌套类中的可变参数模板

  6. 6

    C ++中的嵌套可变参数函数

  7. 7

    可变参数模板中的shared_ptr元组?

  8. 8

    可变参数模板中的shared_ptr元组?

  9. 9

    TypeScript中的可变长度数组元组?

  10. 10

    无法创建可变参数元组

  11. 11

    可变参数嵌套循环

  12. 12

    从可变参数模板数组引用构造函数初始化双嵌套std :: array

  13. 13

    C ++ SFINAE双嵌套的initializer_list与可变参数模板构造函数

  14. 14

    保留参数类型的函数映射数组。TypeScript v4中的可变参数元组类型可以改善这一点吗?

  15. 15

    如何将TypeScript可变参数元组类型用于笛卡尔积函数?

  16. 16

    可变参数模板与使用元组在参数中添加不同的数据对

  17. 17

    将相同的参数转发给C ++中的可变参数元组构造函数

  18. 18

    tidyverse中的双嵌套

  19. 19

    “无法创建可变参数元组”错误

  20. 20

    根据函数的可变参数构建特定的元组

  21. 21

    在Coq中展开嵌套定义

  22. 22

    在C中展开嵌套嵌套循环

  23. 23

    在可变参数模板类的构造函数中初始化元组成员

  24. 24

    在D中,如何在整个元组上指定可变参数模板约束?

  25. 25

    TypeScript可变参数元组类型推断问题,针对运行一系列“结果”返回函数的函数

  26. 26

    可变参数模板展开到std :: tuple

  27. 27

    可变参数模板展开到std :: tuple

  28. 28

    宏中的可变参数

  29. 29

    将可变参数模板参数用于元组失败的向量

热门标签

归档