reactjs 如何将NextJS router.query转换为数字?

46qrfjad  于 2023-03-17  发布在  React
关注(0)|答案(4)|浏览(171)
const router = useRouter()
const { photoId } = router.query

在进行比较时,我收到此Typescript警告:
TS2367:此条件将始终返回“false”,因为类型为“number”和“string|string[]“没有重叠。
这非常合理,所以我将变量类型转换为:

const router = useRouter()
const { photoId } = parseInt(router.query, 10)

但现在我得到警告:
TS2345:类型为“ParsedUrlQuery”的参数无法分配给类型为“string”的参数。
当我查看NextJS路由器的源代码时,我看到了以下内容:

interface ParsedUrlQuery extends NodeJS.Dict<string | string[]> { }

看起来我离得到我需要的东西很近了,它只是一个字符串而不是字符串或字符串数组,我该怎么做?

xuo3flqw

xuo3flqw1#

你可以告诉编译器如何处理变量:

const photoId = parseInt(router.query.photoId as string, 10)

注意,router.query的属性可以是undefined

rkttyhzu

rkttyhzu2#

一种解决方案是以这种方式进行铸造:

const photoId = router.query.photoId ? +router.query.photoId : undefined;

查询属性可能未定义,所以首先检查它是否定义,然后使用一元运算符,或者只返回undefinedinteger的类型将是number | undefined。当然,要记住photoId是否是可以转换为数字的值。
我总是尽量避免使用as,因为typescript已经不可靠了,所以这不会给类型系统本身增加额外的“可信度”。

qco9c6ql

qco9c6ql3#

我还建议使用typescript predicate 而不是直接强制as string。这可以更普遍地用于保证router.query产生类型安全的结果。这有点冗长,但下面的策略有助于比强制转换更好地确保类型安全:

type ExpectedQuery = {
  photoId: string;
}

function isValidQuery(query: ParsedUrlQuery): query is ExpectedQuery {
  // check the query properties
  return typeof (query.photoId) === 'string'
}

const MyComponent: React.FC = () => {
  const router = useRouter();

  if (!isValidQuery(router.query)) {
    // the query isn't what you expected
    // handle it somehow
    return null;
  }

  // Cast to number/undefined
  let photoId = +router.query.photoId

  // Check that it cast correctly
  if (!photoId || isNaN(photoId)) {
    // handle undefined or NaN case
    return null
  }

  // Do stuff with photoId (it's a number so you can do number-like-things)
  photoId += 10;

  return <div>{photoId}</div>
}
bprjcwpo

bprjcwpo4#

正如您提到的,router.query()ParsedUrlQuery对象,我们可以扩展接口,从而添加我们期望接收的路径/查询参数。

interface ParsedUrlQueryForPage extends ParsedUrlQuery {
    photoId: number
}

然后,可以通过这种方式Assertrouter.query的类型

const { photoId } = router.query as ParsedUrlQueryForPage

使用接口扩展的替代方法是交叉点类型

const { photoId } = router.query as ParsedUrlQuery & { photoId : number }

您可以参考本文了解更多详细信息https://reacthustle.com/blog/parse-nextjs-query-params-typescript
您可以在TypeScript文档中阅读有关交集类型以及与接口扩展的区别的更多信息。https://www.typescriptlang.org/docs/handbook/2/objects.html#intersection-types

相关问题