描述
有一个特定的类MachineState<T>
,T
这是它“接受”的类型。我创建了一个函数,可以同时将多个数据点“馈送”给多个 MachineState:
await context.runFunctionsParallel(sign(5), [
[this.#stateBettingOnSport, { id: 3 }], /// [MachineState<A>, A]
[this.#stateBettingOnCasino, { code: "cb12" }], /// [MachineState<B>, B]
]);
实际上,我创建了这个函数:
async runFunctionsParallel<T extends readonly [MachineState<object>, object][]>(signature: SignatureGenerator, values: {
-readonly [K in keyof T]:
T[K] extends [MachineState<infer P>, infer V]
? P extends V
? V extends P
? [MachineState<P>, P]
: never
: never
: never;
}): Promise<unknown[]> {
...
}
问题
该函数不会产生错误,但也无法工作。我没有得到典型的提示和检查。
问题
我的错误在哪里?
补充1
一个不使用数组即可工作的函数定义示例:
async runFunction<T extends {}>(signature: SignatureFunction, state: MachineState<T>, data: T): Promise<unknown> {
...
}
简而言之,现在的问题是什么:
当调用一个函数时,TS 不知道要挂接到什么来确定
T
。在参数类型中,values
这个东西T
应该是“直接”:values: T & {...}
。但这种方法可能会允许额外的键,并且通常不会提示现有的键。如果按照第 1 点的方法进行,T 将作为数组输出。但需要一个元组,否则它可能会跳过类型不匹配。
答案补充
我在操场上做了实验,结果是这样的。
P.1 通过使用三元技巧来解决:
values: T extends unknown ? Pairs<T> : T
。这里,一方面,形式上 T 可以是值的类型,并且 TS 将传递的对象的类型设置为它。另一方面,事实上,条件始终为真,我们转到 Pairs,在那里,基于 T,我们形成所需的类型,并根据该类型对传递的值进行检查。基本上,这个圆圈已经闭合。P.2 由 T 的一个奇怪约束解决,涉及一个元组:
T extends [Item, ...Item[]] | Item[]
。如果没有这个,T 就会被输出为一个数组,即使上面提到的 const 也无济于事。这里没有评论。