【问题标题】:Type that transform entries values?键入转换条目值?
【发布时间】:2022-01-18 22:27:50
【问题描述】:

我想定义一个像这样的类型:

declare type TheOneMillionDollarType<
    Entry extends [string, any], 
    TrMap extends [Entry[1], any]
> = /* TODO */unknown;

这样:

type Input = [ "foo", string ] | [ "bar", number ];

type TrMap = [ string, "string !" ] | [ number, "number !" ];

type Expected = [ "foo", "string !" ] | [ "bar", "number !" ];

type Got = TheOneMillionDollarType<Input, TrMap>;

ExpectedGot 将是同一类型。

非常具体。我要the code of this playground 编译。

【问题讨论】:

  • this approach 适合您吗?只有一个用例很难说,因为可能有很多边缘情况(如果你有["foo", string | number]["foo", unknown] 等怎么办?如果地图看起来像[string | number, "xyz!"] 怎么办?你想要什么?看到了吗?)如果您对我上面写的版本感到满意,我可以写一个答案;否则,请edit这里的代码显示不满意的用例。
  • 恭喜,你解决了!它可以编译,所以它对我有用。请提交您的答案,我会接受。非常感谢

标签: typescript types


【解决方案1】:

一种方法是这样定义它:

type TheOneMillionDollarType<
  E extends [string, any],
  M extends [E[1], any]
  > = E extends unknown ? [E[0], Extract<M, [E[1], any]>[1]] : never;

E extends unknown ? ... : never 类型看起来像一个空操作,但它实际上是一个 distributive conditional type,它将 E 拆分为其 union 成员,评估每个成员的 ... 部分,然后联合(联合?联合?统一?无论如何)结果最终重新组合在一起。

那个类型是[E[0], Extract&lt;M, [E[1], any]&gt;[1]],一个你想要的tuple type,其中第一个元素与E的第一个元素相同。第二个元素使用the Extract&lt;T, U&gt; utility type 过滤M 联合并找到可分配给[E[1], any] 的任何成员。这意味着我们从M 中选择任何成员,其中第一个元素可分配给E 的第二个元素。一旦我们得到它,我们就会对其进行索引 ([1]) 以获取它的第二个元素。

这至少适用于您的示例:

type Got = TheOneMillionDollarType<Input, TrMap>;
// type Got = ["foo", "string !"] | ["bar", "number !"]

请注意,可能存在很多个边缘情况:

type Hmm = TheOneMillionDollarType<["foo", string | number], [string, "a"]>
// type Hmm = ["foo", "a"]
type AlsoHmm = TheOneMillionDollarType<["foo", number], [0, "z"] | [1, "y"]>
// type AlsoHmm = ["foo", "z" | "y"]
type ThirdHmm = TheOneMillionDollarType<["foo", string] | ["bar", number], [string | number, "a"]>;
// type ThirdHmm = ["foo", never] | ["bar", never]

打赌第三个不是你想要的,但也许你不关心那个极端情况。无论如何,我建议您彻底测试,以防您的实际用例结果是TheThreeDollarFiftyCentType

Playground link to code

【讨论】:

    猜你喜欢
    • 2011-03-04
    • 2012-03-07
    • 1970-01-01
    • 1970-01-01
    • 2021-12-11
    • 1970-01-01
    • 1970-01-01
    • 2021-09-05
    • 1970-01-01
    相关资源
    最近更新 更多