【问题标题】:Typescript assistance on wrapper for getServerSideProps关于 getServerSideProps 包装器的打字稿帮助
【发布时间】:2022-10-24 00:24:34
【问题描述】:

我在 Next.js 中为 getServerSideProps 创建了一个身份验证包装器。尽管在钩子中以及在需要它的页面上,但我遇到了一些类型错误。这是包装器代码,后面是 TS 错误。请注意,这是一个非常严格的 TS 实现。

import { deleteCookie, hasCookie } from 'cookies-next'
import { GetServerSideProps } from 'next'

export function withAuth(gssp: GetServerSideProps) {
  return async ctx => { // error 1
    const { req, res } = ctx
    const hasToken = hasCookie('token', { req, res })

    if (!hasToken) {
      deleteCookie('token', { req, res })
      deleteCookie('user', { req, res })
      return {
        redirect: {
          destination: '/login',
          permanent: false,
        },
        props: {},
      }
    }
    const gsspData = await gssp(ctx)

    return {
      props: {
        ...gsspData?.props, // error 2
        hasToken,
      },
    }
  }
}
// error-1:
Parameter 'ctx' implicitly has an 'any' type.ts(7006)

// error-2:
Property 'props' does not exist on type 'GetServerSidePropsResult<{ [key: string]: any; }>'.
  Property 'props' does not exist on type '{ redirect: Redirect; }'.ts(2339)

这也是有错误的实现:

export const getServerSideProps: GetServerSideProps = withAuth(ctx => { // error at CTX
  return { props: {} }
})
// error-3 
Argument of type '(ctx: GetServerSidePropsContext<ParsedUrlQuery, PreviewData>) => { props: {}; }' is not assignable to parameter of type 'GetServerSideProps<{ [key: string]: any; }, ParsedUrlQuery, PreviewData>'.
  Type '{ props: {}; }' is missing the following properties from type 'Promise<GetServerSidePropsResult<{ [key: string]: any; }>>': then, catch, finally, [Symbol.toStringTag]ts(2345)

任何关于此事的启示将不胜感激。提前致谢。

【问题讨论】:

    标签: reactjs typescript next.js server-side-rendering


    【解决方案1】:

    缺少显式类型,并且需要进行一些类型缩小才能使 TypeScript 满意。

    对于第一个错误,因为您使用的是严格类型,TypeScript 会抱怨因为 ctxany 的隐式类型。您可以使用GetServerSidePropsContext 正确键入ctx

    对于第二个错误,TypeScript 自身无法确定 gsspData 的正确类型(在它可能拥有的类型之外),因此我们可以通过使用 'props' in gsspData ? gsspData.props : {} 缩小范围来帮助解决这个问题。这种缩小确保props 存在于gsspData 中,因此我们可以安全地调用gsspData.props

    import { deleteCookie, hasCookie } from 'cookies-next'
    import { GetServerSideProps } from 'next'
    
    export function withAuth(gssp: GetServerSideProps) {
        // Explicitly type `ctx` as `GetServerSidePropsContext`
        return async (ctx: GetServerSidePropsContext) => {
            const { req, res } = ctx
            const hasToken = hasCookie('token', { req, res })
    
            if (!hasToken) {
                deleteCookie('token', { req, res })
                deleteCookie('user', { req, res })
    
                return {
                    redirect: {
                        destination: '/login',
                        permanent: false
                    }
                    // No need to return `props` when redirecting
                }
            }
    
            const gsspData = await gssp(ctx)
    
            return {
                props: {
                    // Narrow down `gsspData` type
                    ...('props' in gsspData ? gsspData.props : {}),
                    hasToken
                }
            }
        }
    }
    

    最后,传递给withAuth 的函数需要返回一个promise(因为它的类型为gssp: GetServerSideProps)。我们可以通过创建函数async 来简单地修复错误。

    export const getServerSideProps: GetServerSideProps = withAuth(async (ctx) => {
        // Your logic here
        return { props: {} }
    })
    

    【讨论】:

      猜你喜欢
      • 2021-08-15
      • 2020-11-08
      • 1970-01-01
      • 1970-01-01
      • 2011-09-13
      • 1970-01-01
      • 1970-01-01
      • 2013-11-14
      • 1970-01-01
      相关资源
      最近更新 更多