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

Preact useState类型疑问:((prevState: null) => null) | null含义等问题

Preact useState 类型问题解答

问题场景

先看这段Preact代码:

import { useState } from "preact/hooks";
export default function Test() {
  const [state, setState] = useState(null); 
  setState('string');
}

运行时会抛出TypeScript错误:

Argument of type 'string' is not assignable to parameter of type '(prevState: null) => null'.deno-ts(2345)

如果把初始值换成数字1:

-   const [state, setState] = useState(null); 
+   const [state, setState] = useState(1); 

错误提示变成:

Argument of type 'string' is not assignable to parameter of type 'number | ((prevState: number) => number)'.deno-ts(2345)

疑惑解答

1. ((prevState: null) => null) | null 是什么含义?

这是TypeScript的联合类型,表示这个位置的取值只能是以下两种类型之一:

  • 一个函数:接收类型为null的prevState参数,返回值必须也是null
  • 直接传入null值
    简单说就是调用setState时,要么传null,要么传一个能把旧的null状态转换成新null的函数。

2. 为什么初始值为null时,要求的类型不是 null | ((prevState: null) => null)?

这是TypeScript类型推导的特性:当你给useState传入null作为初始值时,TypeScript会把状态类型推导为单一的null类型(而非包含null的联合类型)。此时setState的参数类型实际上是null | ((prevState: null) => null),但你传入的'string'既不是null也不符合函数类型,TypeScript在报错时优先展示了和传入值差异较大的函数类型。

而当初始值是1(数字字面量)时,TypeScript推导状态类型为number,setState的参数类型是number | ((prevState: number) => number)——这里错误提示列出了完整的联合类型,是因为string和这两个类型都不匹配,所以TypeScript把所有可选类型都展示了出来。

3. 如何使用多类型状态?例如初始值为1或null,后续将值设置为'string'?

需要手动给useState指定联合类型,明确声明状态允许的所有类型:

import { useState } from "preact/hooks";
export default function Test() {
  // 明确指定状态可以是 number、null 或 string
  const [state, setState] = useState<number | null | string>(1); 
  setState('string'); // 正常运行,无报错
  setState(null);     // 支持设置为null
  setState(2);        // 支持设置为数字
}

如果初始值是null,想要后续支持其他类型,同样手动指定联合类型即可:

const [state, setState] = useState<string | null>(null);
setState('hello'); // 正常工作

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 10:03:14