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

React中设置状态时如何正确提供类型?使用useState存储对象传递setState至子组件出现TypeScript错误的排查

嘿,我来帮你拆解这个TypeScript错误的问题,顺便聊聊React状态类型定义的正确姿势~

先看错误的根源

你遇到的错误Argument of type '(oldPerson: any) => any' is not assignable to parameter of type 'Person',本质是状态类型和更新函数的返回值不匹配,具体有两个关键点:

  1. 你给useState指定的泛型是Person | null,意味着setPerson接受的参数要么是Person | null,要么是一个返回Person | null的函数。但你的更新函数里没有处理oldPerson为null的情况,TypeScript没法自动推断oldPerson的类型,只能默认给any,返回值也变成了any,和你定义的Person | null类型不兼容。
  2. 你的初始状态没有明确赋值(只写了useState<Person | null>()),这会让状态的初始值是undefined,进一步加剧了类型推断的混乱。

修复方案

根据你的业务需求,有两种常见的修复方式:

方案1:避免null状态,给初始值匹配Person类型

如果你的person状态不应该为null,直接给一个符合Person类型的初始值,这样TypeScript能完美推断类型:

interface Person { 
  name: string 
  age: number 
  job: string 
} 

// 给初始状态一个符合Person类型的默认值
const [person, setPerson] = useState<Person>({
  name: "",
  age: 0,
  job: ""
}) 

const updateOldPerson = { age: 70 } 
// 此时oldPerson会被自动推断为Person类型,返回值也符合要求
setPerson((oldPerson) => ({ ...oldPerson, ...updateOldPerson }))

方案2:保留Person | null类型,处理null分支

如果业务上person确实可能为null,那在更新函数里必须处理oldPerson为null的情况,确保返回值符合Person | null的类型:

interface Person { 
  name: string 
  age: number 
  job: string 
} 

// 明确初始值为null
const [person, setPerson] = useState<Person | null>(null) 

const updateOldPerson = { age: 70 } 
setPerson((oldPerson) => {
  // 处理oldPerson为null的情况,比如返回默认Person对象或null
  if (!oldPerson) {
    return { name: "", age: 70, job: "" };
  }
  return { ...oldPerson, ...updateOldPerson };
})

React状态的TypeScript类型定义最佳实践

这里给你总结几个常用的正确姿势:

  • 明确指定泛型类型:当状态有固定结构时,直接在useState后通过<>声明类型,比如useState<Person>(initialValue);如果状态可能为null/undefined,把这些情况加入泛型,比如useState<Person | null>(null)。
  • 初始值要匹配类型:初始值必须符合你指定的泛型类型,避免TypeScript自动推断出不符合预期的类型(比如你之前没给初始值,导致状态包含undefined)。
  • 函数式更新的类型推断:使用函数式更新时,TypeScript会根据useState的泛型自动推断旧状态的类型,不用手动指定;但如果是联合类型(比如Person | null),一定要处理所有分支,确保返回值符合类型要求。
  • 子组件传递setState的类型:如果要把setPerson传给子组件,可以用React.Dispatch<React.SetStateAction<Person>>来定义类型,比如:
    // 定义setPerson的类型
    type PersonSetter = React.Dispatch<React.SetStateAction<Person>>;
    
    const ChildComponent = ({ setPerson }: { setPerson: PersonSetter }) => {
      const handleUpdate = () => {
        setPerson(old => ({ ...old, age: old.age + 5 }));
      };
      return <button onClick={handleUpdate}>增加5岁</button>;
    };
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 04:54:06