我可以使用映射条件类型从记录类型映射到函数类型吗?

Can I map from a record type to a function type using mapped conditional types?

在 Typescript 中给定以下类型

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

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

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

不是真的。无法以任何可预测或可用的顺序枚举对象的键。你可以一些程序化的东西,但你必须从更容易操作的类型开始,像这样:

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

这是一个 2 元组的元组,表示您的类型中的 key-value 对。然后您可以使用(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

请注意如何没有程序化的方法来执行 variable-length 参数列表,因此您能做的最好的事情就是像上面那样将 case 设置为某个固定的最大长度。让我们验证一下:

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

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

所以这是一个很长的 drawn-out 多次表达 "not really" 的方式。哦,好吧,也许无论如何它都有一些帮助。祝你好运!