React转TypeScript遇类型错误:AuthContext与SearchFilter问题求助
问题1:AuthContext 类型缺失导致
loggedIn 属性不存在错误 错误原因
创建AuthContext时传入的初始值是空对象{},TypeScript会推断上下文类型为{},因此useAuthContext()返回的对象不包含loggedIn等属性,引发类型错误。
解决方案
修改AuthContext.ts,添加明确的上下文类型定义,并完善hook的类型检查逻辑:
import { useState, createContext, useContext, ReactNode, Dispatch, SetStateAction } from "react"; import { useNavigate } from "react-router-dom"; // 定义AuthContext的完整类型 type AuthContextType = { loggedIn: boolean; setLoggedIn: Dispatch<SetStateAction<boolean>>; selectedDogs: number[]; setDogMatch: (data: number[]) => void; }; // 创建上下文,初始值设为undefined,后续由Provider注入真实值 const AuthContext = createContext<AuthContextType | undefined>(undefined); export function useAuthContext() { const context = useContext(AuthContext); // 强制hook必须在AuthProvider内部使用,避免运行时错误 if (!context) { throw new Error("useAuthContext must be used within an AuthProvider"); } return context; } type AuthProviderProps = { children: ReactNode; }; export function AuthProvider({ children }: AuthProviderProps) { const [loggedIn, setLoggedIn] = useState<boolean>( localStorage.getItem("loggedIn") === "true" ); const [selectedDogs, setSelectedDogs] = useState<number[]>([]); const navigate = useNavigate(); function setDogMatch(data: number[]) { setSelectedDogs(data); navigate("/dog-match"); } return ( <AuthContext.Provider value={{ loggedIn, setLoggedIn, selectedDogs, setDogMatch, }} > {children} </AuthContext.Provider> ); }
同时修正ProtectedRoute的props类型,避免使用any:
import { Navigate } from "react-router-dom"; import { useAuthContext } from "../context/AuthContext"; import { ReactNode } from "react"; type ProtectedRouteProps = { children: ReactNode; }; export const ProtectedRoute = ({ children }: ProtectedRouteProps) => { const { loggedIn } = useAuthContext(); if (!loggedIn) { return <Navigate to="/" />; } return children; };
问题2:SearchFilters 组件参数隐式
any 类型错误 错误原因
组件的props和map中的data参数未指定类型,TypeScript默认推断为any,违反严格类型检查规则。
解决方案
定义组件props的类型(包含自定义属性和react-select的内置属性),修正参数类型:
import Select, { SelectProps } from "react-select"; // 定义react-select的选项结构 type FilterOption = { value: string | number; label: string | number; }; // 组合自定义属性与react-select的内置属性 type SearchFiltersProps = SelectProps<FilterOption, boolean> & { name: string; data?: (string | number)[]; // data为可选,部分调用直接传入options }; export default function SearchFilters(props: SearchFiltersProps) { // 将原始data转换为react-select需要的选项格式 const options = props.data?.map((item) => ({ value: item, label: item, })); // 优先使用传入的options,否则用转换后的结果 const finalOptions = props.options || options; return ( <div className="dropdown-container"> <h4>{props.name}</h4> <Select options={finalOptions} isSearchable={true} {...props} /> </div> ); }
说明
FilterOption适配了字符串/数字类型的选项值,符合你API返回的数据格式SearchFiltersProps继承了react-select的SelectProps,支持isMulti、onChange等内置属性- 处理了
data和options两种传参方式,适配不同场景的组件调用
内容的提问来源于stack exchange,提问作者NewBeeee
相关产品推荐
相关产品推荐

