You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React useContext传递useState属性时触发TypeScript类型错误

解决React Context结合TypeScript时的属性不存在错误

你遇到的错误核心是Context的类型定义过于宽泛:使用<Object>作为createContext的泛型参数后,TypeScript无法识别currentUser和setCurrentUser这两个自定义属性,因此解构时会提示属性不存在。

以下是具体修复步骤:

步骤1:定义Context的具体类型接口

先明确描述Context的结构,同时定义用户数据的类型:

// 定义用户数据的类型
interface User {
  name: string;
}

// 定义Context的完整类型
interface CurrentUserContextType {
  currentUser: User | null;
  setCurrentUser: React.Dispatch<React.SetStateAction<User | null>>;
}

步骤2:用正确类型创建Context

替换原来的createContext<Object>({}),使用上面定义的接口,并提供符合类型的默认值(避免组件在Provider外部使用时报错):

const CurrentUserContext = createContext<CurrentUserContextType>({
  currentUser: null,
  setCurrentUser: () => {}, // 空函数作为默认的setter
});

步骤3:修正useState的类型

原来的useState(null)会被TypeScript推断为null类型,需要明确指定为User | null:

const [currentUser, setCurrentUser] = useState<User | null>(null);

完整修复后的代码

import { createContext, useContext, useState, ReactNode, DetailedHTMLProps, ButtonHTMLAttributes, MouseEventHandler } from 'react';

// 新增用户类型定义
interface User {
  name: string;
}

// 新增Context类型定义
interface CurrentUserContextType {
  currentUser: User | null;
  setCurrentUser: React.Dispatch<React.SetStateAction<User | null>>;
}

// 用正确的类型创建Context并设置符合类型的默认值
const CurrentUserContext = createContext<CurrentUserContextType>({
  currentUser: null,
  setCurrentUser: () => {},
});

export default function MyApp() {
  // 明确useState的类型
  const [currentUser, setCurrentUser] = useState<User | null>(null);
  return (
    <CurrentUserContext.Provider
      value={{
        currentUser,
        setCurrentUser
      }}
    >
      <Form />
    </CurrentUserContext.Provider>
  );
}

function Form(): JSX.Element {
  return (
    <Panel title="Welcome">
      <LoginButton />
    </Panel>
  );
}

function LoginButton(): JSX.Element {
  const {
    currentUser,
    setCurrentUser
  } = useContext(CurrentUserContext);

  if (currentUser !== null) {
    return <p>You logged in as {currentUser.name}.</p>;
  }

  return (
    <Button onClick={() => {
      setCurrentUser({ name: 'Advika' })
    }}>Log in as Advika</Button>
  );
}

interface PanelProps {
  title: string
  children: ReactNode
}

function Panel({ title, children }: PanelProps): JSX.Element {
  return (
    <section className="panel">
      <h1>{title}</h1>
      {children}
    </section>
  )
}

interface ButtonProps extends DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement> {
  children: ReactNode
  onClick?: MouseEventHandler<HTMLButtonElement>
}

function Button({ children, onClick }: ButtonProps): JSX.Element {
  return (
    <button className="button" onClick={onClick}>
      {children}
    </button>
  );
}

内容的提问来源于stack exchange,提问作者Lvasche

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 22:01:01