我正在为项目的 Express 创建一个路由处理程序创建器,并且我正在尝试创建它,以便您可以在传递路由处理程序回调之前传递任意断言作为初始参数。像这样的东西:
const myHandler = makeHandler(assertion1(), assertion2(), (data, req, res, next) => {
// data is an array of the results of the assertions
});
我可以获得一些我想要的类型“工作”方式的版本:
// express namespace omitted for brevity; see playground link above.
type Assertion<T = unknown> = (req: express.Request) => T;
type ReturnTypes<A extends ReadonlyArray<Assertion>> = {
[K in keyof A]: ReturnType<A[K]>;
};
function assertion1<T extends object>(arg: T) {
return () => arg
}
function assertion2() {
return () => "yes"
}
const a = assertion1({ something: "yes" })
const b = assertion2()
// This type works as expected: it is [{ something: string }, string]
type d = ReturnTypes<[typeof a, typeof b]>
然而,当我尝试让它作为上面的参数的可变版本工作时makeHandler
,有些东西似乎不起作用,data
上面示例中的类型是unknown[]
:
// the logic for `makeHandler` is omitted for brevity
declare function makeHandler<
Assertions extends Assertion<unknown>[]
>(...assertionsAndCb: [...Assertions, HandlerCb<ReturnTypes<Assertions>>]): void
// `data` here doesn't seem to be typed correctly. For some reason it's of type unknown[], rather than
// the same as type `d` above.
makeHandler(assertion1({ hey: "what"}), assertion2(), (data, req) => {
return { response: {} }
})
我读过一些关于这可能如何适用于类似的东西zip
(并且我的函数很大程度上基于这个要点),但我正在努力让实际类型正确通过。我在这里缺少什么东西吗?例如,我没有正确地推断出一些通用的东西?