如果我有这个代码:

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

然后我得到了这个错误:

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

我知道它希望我使用与初始类型相同的值类型.但是,如果初始值是实际的类似文字的数字:

-   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)

阅读What is prevState in ReactJS?Hooks – Preact Guide并不能帮助我理解:

  • ((prevState: null) => null) | null是什么意思
  • 为什么第一个 case 所需的类型不是null | ((prevState: null) => null)
  • 如何使用多种类型?例如,初始值是1或null,但我随后将值设置为'string'

推荐答案

虽然你的问题得到了部分回答,但我认为你的第二个问题仍然没有得到回答.所以我还是会提交这一条:

回答三个问题:

  1. React需要新的状态值或状态更新器函数.因此,由于您的状态类型被推断为null,TS编译器只是在抱怨它可能需要null(新状态值)或((prevState: null) => null) | null(状态更新器函数).此方法应根据先前的值返回一个新值.Doc

  2. unions中的null类型通常被合并到其他类型中.

请看下面的代码.

let x : null| number  = 'string';

错误是Type 'string' is not assignable to type 'number'.而不是Type 'string' is not assignable to type 'number | null'.

enter image description here

现在,如果我们写如下:

let y : null  = 'string';

错误将是:

enter image description here

正如你所看到的,没有遗漏null,因为没有unions .

Playground Link for the above

这是上面发生的事情的一个微不足道的例子.当代码更改为:

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

错误与预期一致,现在包括unions 的number部分:

'number | ((prevState: number) => number)'

  1. 对于多种类型,就像 comments 中提到的那样,只需使用类似union的符号,就可以了:
const [val,setVal] = useState<number | null | string | boolean>(null)

Edit: 如果你热衷于在你的错误中得到null分,根据所涉及的TS版本,你可以调整它.

下面的playground 正在使用TS 4.x.x,我可以通过点击TS配置按钮来启用/禁用strictNullChecks.一旦您启用strictNullChecks

Playground

strictNullChecks他说的话.它开始包括null(和undefined)在您的支票(在这种情况下是unions )

Doc

Typescript相关问答推荐

使用FormArray在Angular中添加排序

如何使打包和拆包功能通用?

typescribe不能使用值来索引对象类型,该对象类型满足具有该值的另一个类型'

具有继承的基于类的react 组件:呈现不能分配给基类型中的相同属性

<;T扩展布尔值>;

表单嵌套太深

Select 下拉菜单的占位符不起作用

一个打字类型可以实现一个接口吗?

如何在react组件中使用doctype和html标签?

为什么在leetcode问题的测试用例中,即使我确实得到了比预期更好的解决方案,这段代码也失败了?

类型脚本可以推断哪个类型作为参数传递到联合类型中吗?

不带其他属性的精确函数返回类型

使用泛型识别对象值类型

类型脚本-处理值或返回值的函数

Angular 16将独立组件作为对话框加载,而不进行布线或预加载

Typescript,如何在通过属性存在过滤后重新分配类型?

参数未映射泛型返回类型

在对象数组中设置值

在类型{}上找不到带有string类型参数的索引签名 - TypeScript

如何按成员资格排除或 Select 元组?