【问题标题】:Why is Typescript not recognizing the type I'm giving to my `useState` state variables?为什么 Typescript 无法识别我赋予我的“useState”状态变量的类型?
【发布时间】:2021-12-17 10:31:45
【问题描述】:

为什么会出现以下代码:

import React, {Dispatch, SetStateAction, useState} from 'react'

type Fn = () => void

export const Component = () => {
  const [fn, setFn]: [Fn, Dispatch<SetStateAction<Fn>>] = useState(() => {})

  return <p>{`${typeof fn}, ${typeof setFn}`}</p>
}

产生以下 Typescript 错误:

类型“[void, Dispatch]”不可分配给类型“[Fn, Dispatch]”。

源中位置 0 处的类型与目标中位置 0 处的类型不兼容。

类型 'void' 不可分配给类型 'Fn'.ts(2322)

常量 fn: Fn

?

您可以亲自查看此操作here

我的看法:

  • 我给useState 一个默认值() =&gt; {},它的类型是() =&gt; void
  • 我声明了一个fn 类型为Fn 又名() =&gt; void 的常量
  • 这些类型完全相同,不是void

那么为什么 Typescript 指的是Type '[void, Dispatch&lt;SetStateAction&gt;]'?

它是从哪里得到这种类型的?

我创建的唯一类型 (afaik) 是 Type '[Fn, Dispatch&lt;SetStateAction&lt;Fn&gt;&gt;]',还是我做错了什么?

作为一个后续问题:是否有更简洁的方法来严格键入这种东西?

【问题讨论】:

  • type () => {} 不同于 () => void
  • @Woohaik 你是说const fn = () =&gt; {} 中的函数fn 不是() =&gt; void 类型吗?这是一个不返回任何内容的函数……
  • 如果您为() =&gt; {} 编写一个类型,为() =&gt; void 编写另一个类型,请在不同的变量中使用两者,然后尝试将变量分配给另一个变量,您将得到Type 'void' is not assignable to type '{}'
  • 我不得不问这个,我知道() =&gt; {}() =&gt; void 不一样,但这就是为什么,() =&gt; {} 不是一个空函数,它实际上是一个返回的函数像这样的空对象:const someFn : () =&gt; {} = () =&gt; {return {} } 这就是打字稿不同的原因。让我感到困惑,我知道与您的问题没有直接关系,但我认为值得澄清。
  • @Woohaik 这不是我在上面的代码中所做的。相反,我声明了一个函数() =&gt; {}(在第6行作为useState的默认值),类型为() =&gt; void(在第3行定义为Fn类型);更像这样的东西:const fn: () =&gt; void = () =&gt; {}; console.log(fn()) // prints 'undefined'.

标签: typescript react-hooks use-state


【解决方案1】:

如果删除类型注释,您会看到fn 的类型被推断为void

发生这种情况是因为,如果将函数传递给useStatethis is taken as a callback that React runs to determine the initial state。这是一种不调用确定每次渲染初始状态的昂贵进程的方法。

如果你想让状态成为一个函数,你需要将它嵌套在另一个函数中。

const [fn, setFn] = useState(() => () => {})

无需显式注明类型 - TypeScript 可以自动推断。

【讨论】:

  • 啊,我忘记useState的这个功能了。我以为我误解了 Typescript 本身。现在我更正了默认值,我确实可以删除所有类型注释并让 Typescript 自动推断它们。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-17
  • 2020-05-28
  • 2019-05-27
相关资源
最近更新 更多