关于useParam<xx>报错,麻烦老师看一下

来源:10-3 【详情页面搭建 1】页面框架、详情与日期选择

幕布斯7094097

2022-05-12

以下是我的detail组件,其中在useParam<MatchParams>时报错了,错误如下代码,但是换了后面两种写法则没有报错,请问老师·这是什么原因呢?

import React, { useState } from "react";
import { useParams } from "react-router-dom";
import axios from "axios";

interface MatchParams {
  touristRouteId: string;
}

type MatchParams1 = {
  touristRouteId: string;
};

export const Detail: React.FC = () => {
  // 报错 Type 'MatchParams' does not satisfy the constraint 'string | Record<string, string | undefined>'.
  // Type 'MatchParams' is not assignable to type 'Record<string, string | undefined>'.
  // Index signature for type 'string' is missing in type 'MatchParams'.ts(2344)
  // const { touristRouteId } = useParams<MatchParams>();
  
  // 不报错
  // const { touristRouteId } = useParams<{touristRouteId: string}>();
  
  // 不报错
  // const { touristRouteId } = useParams<MatchParams1>();
  return <></>;
};
写回答

2回答

阿莱克斯刘

2022-05-16

https://img.mukewang.com/szimg/6282105709c88af019920676.jpg

这是最新版react-router的一个变化,如果把鼠标放在useParams上我们可以看到,这个方法的范型类型其实应该是一个字符串。所以,我们的正确写法应该是下面的图片所示。

https://img.mukewang.com/szimg/628210c309218c7f15700274.jpg

但是,回到你的问题,为什么我们可以使用type却不能使用interface呢?

大部分情况下interface 和 type是可以互换的,但是有那么几个情况我们只能使用type不能使用interface,那就是如果我们需要对某个类型进行重命名的时候。

比如说,我们可以让一个type等于一个字符串,但是,没有办法让一个接口等于这个字符串。

type str = "touristRouteId"; // 对
interface int = "touristRouteId"; // 错

而 useParams 的本质需要我们输入的是一个字符串类型,而不是对象化的类型。所以,我们可以在useParams 中使用type,却不能使用interface。(而你的追问中的解决方案实际上是让interface的key类型变为string来达到使用目的的,这个不建议使用)

那么使用type来定义useParams的好处是什么呢?假如说,我们的url中有多个参数,那么我们就可以用type来定义参数了。


对了,顺便提一下,课程正在做升级,会升级到react18,也会升级react router和其他所有的插件,预计6月会上线。

1
1
幕布斯7094097
十分感谢老师的详细解答!
2022-05-16
共1条回复

幕布斯7094097

提问者

2022-05-14

然后这样写interface后又可以了,好困惑啊:

interface MatchParams {
  keywords: string;
  [key: string]: string;
}


0
0

React18 系统精讲 结合TS打造旅游电商平台

React18 精讲 + 结合 TS 实战 + 热门业务开发,获取必备技能

1993 学习 · 1015 问题

查看课程