50

我无法弄清楚如何键入useState函数,因为它返回一个元组。本质上,我必须提供null初始值,email即假设我不能在这里使用空字符串。

然后我有setEmail更新这个状态值的功能,它将电子邮件作为字符串。

理想情况下,我想输入 my useState,因此如果可能的话,它希望电子邮件为字符串或 null。目前它只继承它null

import * as React from "react";

const { useState } = React;

function Example() {
  const [state, setState] = useState({ email: null, password: null });

  function setEmail(email: string) {
    setState(prevState => ({ ...prevState, email }))
  }

  return <p>{state.email}</p>
}

函数返回以下错误,setEmail因为string函数参数不是null指定的有效类型useState()

[ts]
Argument of type '(prevState: { email: null; password: null; }) => { email: string; password: null; }' is not assignable to parameter of type 'SetStateAction<{ email: null; password: null; }>'.
  Type '(prevState: { email: null; password: null; }) => { email: string; password: null; }' is not assignable to type '(prevState: { email: null; password: null; }) => { email: null; password: null; }'.
    Type '{ email: string; password: null; }' is not assignable to type '{ email: null; password: null; }'.
      Types of property 'email' are incompatible.
        Type 'string' is not assignable to type 'null'. [2345]
(parameter) prevState: {
    email: null;
    password: null;
}
4

3 回答 3

77

目前,TypeScript 编译器认为emailand passwordare的类型null(并且没有其他值)。您可以通过向调用提供显式类型参数来解决此问题,useState以便 和 的类型email已知passwordstringor null

const { useState } = React;

function Example() {
  const [state, setState] = useState<{email: null | string, password: null | string}>({ email: null, password: null });

  function setEmail(email: string) {
    setState(prevState => ({ ...prevState, email }))
  }

  return <p>{state.email}</p>
}
于 2018-11-16T13:50:25.667 回答
23

这已经在几个地方得到解决:

https://dev.to/busypeoples/notes-on-typescript-react-hooks-28j2

https://codewithstyle.info/Using-React-useState-hook-with-TypeScript/

TLDR:当初始状态为空时,将类型参数传递给 setState

例如:

const [email, setEmail] = useState<string>();
于 2020-05-15T15:42:40.520 回答
0

您可以使用 TS 映射类型来提高可读性并更喜欢 undefined 而不是 null 值

const { useState } = React;

function Example() {
  const [state, setState] = useState<Partial<{email: string, password: string}>>();

  function setEmail(email: string) {
    setState(prevState => ({ ...prevState, email }))
  }

  return <p>{state.email | ""}</p>
}
于 2019-07-09T14:30:48.787 回答