NodeJS 为express-zod-API的const中间件提供类型

ikfrs5lh  于 11个月前  发布在  Node.js
关注(0)|答案(1)|浏览(91)

我有一个NodeJS服务器,在那里我使用express-zod-api来验证输入和响应。我们使用类似这样的东西来链接中间件:

const workingExample = defaultEndpointsFactory.addMiddleware(createMiddleware({
    input: z.object({}),
    middleware: async () => {
        return {
            id: "an id",
        }
    }
})).addMiddleware(createMiddleware({
    input: z.object({}),
    middleware: async ({options}) => {
        console.log(`this is typed as a string: ${options.id}`)
        return {
            ...options,
            something: "else",
        }
    },
}))

字符串
然而,我想使用像lego这样的中间件-我并不总是想要相同的中间件以相同的顺序,所以我将它们提取为单独的常量:

const middlewareA = createMiddleware({
    input: z.object({}),
    middleware: async () => {
        return {
            id: "an id",
        }
    },
})

const middlewareB = createMiddleware({
    input: z.object({}),
    middleware: async ({ options }) => {
        console.log(`this fails because option is "unknown": ${options.id}`)
        return {
            ...options, // TS2698: Spread types may only be created from object types.
            something: "else",
        }
    },
})

const brokenExample = defaultEndpointsFactory
    .addMiddleware(middlewareA)
    .addMiddleware(middlewareB)


这给了我TS错误,因为options对象是unknown。在工作示例中,中间件直接链接,我想TypeScript可以找出options应该是什么。
我想我需要为TypeScript提供更多的信息,例如:

const middlewareB: MiddlewareDefinition<any, any, any, any> = createMiddleware({


我可以煞费苦心地弄清楚any应该是什么,但这会使一切都变得非常不灵活,特别是如果我混合和匹配中间件的话。有没有可能将middlewareAmiddlewareB通用化.做正确的事情,让TS来弄清楚?
样品复制:https://github.com/crummy/express-zod-middleware

6ovsh4lw

6ovsh4lw1#

我设法设法找到了一个解决这个问题的比较好的办法。

const middlewareA = async () => {
        return {
            id: "an id",
        }
    }

const middlewareB =  async ({ options }: { options: {  id: string } }) => {
        console.log(`this does not work because options is "any": ${options.id}`)
        return {
            ...options,
            something: "else",
        }
    }

const brokenExampleFixed = defaultEndpointsFactory
    .addMiddleware(createMiddleware({
        input: z.object({}),
        middleware: middlewareA
    }))
    .addMiddleware(createMiddleware({
        input: z.object({}),
        middleware: middlewareB,
    }))

字符串
使用这种方法,我可以共享中间件,只需要显式输入他们需要的输入部分,而Zod + TypeScript处理所有其他部分。

相关问题