使用useLoaderData与shadcn-ui DataTable时的TypeScript类型错误
解决useLoaderData与shadcn-ui DataTable的类型不匹配问题
问题根源
useLoaderData 默认返回类型为 unknown,而shadcn-ui的DataTable要求data属性必须是定义好的PatientColumn[]类型;同时在Heading组件中访问data?.length时,unknown类型也会触发类型检查错误。
解决方案
1. 为Loader函数指定返回类型
给patientDataLoader明确标注返回类型为Promise<PatientColumn[]>,同时让axios请求指定响应数据类型,确保TypeScript能识别返回数据的结构:
export const patientDataLoader = async (): Promise<PatientColumn[]> => { // 给axios.get指定泛型,明确响应数据类型 const response = await axios.get<PatientColumn[]>("http://localhost:3000/api/patients"); return response.data; }
2. 为useLoaderData返回值做类型断言
由于部分版本的react-router-dom中useLoaderData不支持直接传入泛型参数,我们可以通过类型断言将返回值转为PatientColumn[]:
const DashboardPage: React.FC = () => { const navigate = useNavigate(); // 类型断言明确data的类型 const data = useLoaderData() as PatientColumn[]; return ( // ... 原有JSX代码 ); };
3. 验证类型匹配
修改后,data的类型变为PatientColumn[],既满足DataTable对data属性的类型要求,也能正常访问data.length而不触发类型错误。
修改后的完整代码片段
import { ColumnDef } from "@tanstack/react-table"; import { Plus } from "lucide-react"; import { Button } from "@/components/ui/button"; import Heading from "@/components/ui/heading"; import { Separator } from "@/components/ui/separator"; import { DataTable } from "@/components/ui/data-table"; import { useLoaderData, useNavigate } from "react-router-dom"; import axios from "axios"; type PatientColumn = { id: string; fullName: string; age: string; sex: string; phone: string; email: string; doctor: string; injury: string; dateOfVisit: string; }; // 明确Loader返回类型 export const patientDataLoader = async (): Promise<PatientColumn[]> => { const response = await axios.get<PatientColumn[]>("http://localhost:3000/api/patients"); return response.data; } const DashboardPage: React.FC = () => { const navigate = useNavigate(); // 类型断言转换数据类型 const data = useLoaderData() as PatientColumn[]; return ( <div className="flex-col"> <div className="flex-1 space-y-4 p-8 pt-1"> <div className="flex items-center justify-between"> <Heading title={`Patients List (${data.length || 0})`} description="Manage patients information " /> <Button onClick={() => navigate(`/dashboard/patient`)}> <Plus className="mr-2 w-4 h-4" /> Add New </Button> </div> <Separator /> <DataTable columns={columns} data={data} searchKey="fullName"/> </div> </div> ); }; export default DashboardPage; const columns: ColumnDef<PatientColumn>[] = [ { accessorKey: "fullName", header: "Full name", }, { accessorKey: "age", header: "Age", }, { accessorKey: "sex", header: "Sex", }, { accessorKey: "phone", header: "Phone", }, { accessorKey: "email", header: "Email", }, { accessorKey: "doctor", header: "Doctor", }, { accessorKey: "injury", header: "Injury", }, { accessorKey: "dateOfVisit", header: "Date", }, ];
内容的提问来源于stack exchange,提问作者ayex
相关产品推荐
相关产品推荐

