【问题标题】:Can I map from a record type to a function type using mapped conditional types?我可以使用映射条件类型从记录类型映射到函数类型吗?
【发布时间】:2018-04-01 03:00:11
【问题描述】:

给定 Typescript 中的以下类型

type MyType = {
    foo: int,
    bar: string
}

我可以定义一个映射(最好使用映射的条件类型)以便我得到

type MyTypeFn = (foo: int, bar: string) => MyType

【问题讨论】:

  • 它是number 不是int,但不管怎样,我认为没有办法做到这一点,打字稿中没有映射函数。您可以定义type Create<T> = (o:T) => T,但这并没有增加太多价值..

标签: typescript mapped-types


【解决方案1】:

不是真的。无法以任何可预测或可用的顺序枚举对象的键。您可以以编程方式进行一些事情,但您必须从更容易操作的类型开始,如下所示:

type MySchema = [['foo', number], ['bar', string]]

这是一个 2 元组的元组,表示您的类型中的键值对。然后您可以使用(TSv2.8 及更高版本)类型函数合成MyType,例如:

type MakeMyType<S extends [string, any][], M = S[number]> = 
  { [K in S[number][0]]: M extends [K, any] ? M[1] : never }

您可以验证:

type MyType = MakeMyType<MySchema>
// inspects as { foo: number; bar: string }

然后你可以合成MyTypeFn 使用类型函数,例如:

type MakeMyFunction<S extends [string, any][], L = S['length'], T = MakeMyType<S>> =
  L extends 0 ? () => T :
  L extends 1 ? (a0: S[0][1]) => T :
  L extends 2 ? (a0: S[0][1], a1: S[1][1]) => T :
  L extends 3 ? (a0: S[0][1], a1: S[1][1], a2: S[2][1]) => T :
  L extends 4 ? (a0: S[0][1], a1: S[1][1], a2: S[2][1], a3: S[3][1]) => T :
  L extends 5 ? (a0: S[0][1], a1: S[1][1], a2: S[2][1], a3: S[3][1], a4: S[4][1]) => T :
  L extends 6 ? (a0: S[0][1], a1: S[1][1], a2: S[2][1], a3: S[3][1], a4: S[4][1], a5: S[5][1]) => T :
  (...args: S[number][1][]) => T

请注意,没有编程方式来处理可变长度参数列表,因此您能做的最好的事情就是使案例达到上述某个固定的最大长度。让我们验证一下:

type MyTypeFn = MakeMyFunction<MySchema>
// inspects as (a0: number, a1: string) => { foo: number; bar: string; }

是的,参数名称也丢失了(foobar 变为 a0a1)。这不会影响函数签名的类型兼容性,其中参数名称并不重要。但我猜你想要这些参数名称在使用或实现函数时进行提示。如果是这样,那就是另一个“不是真的”。

所以说“不是真的”多次是一种冗长的方式。哦,好吧,无论如何,也许它有一些帮助。祝你好运!

【讨论】:

    猜你喜欢
    • 2023-01-29
    • 2019-03-21
    • 2020-05-16
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 2019-04-06
    • 2022-01-13
    相关资源
    最近更新 更多