Tengo problemas para averiguar cómo escribir la función useState ya que devuelve una tupla. En esencia, tengo que proporcionar un valor null como valor inicial para el email , es decir, supongamos que no puedo usar una cadena vacía aquí.
Luego tengo la función setEmail para actualizar este valor de estado, que toma el correo electrónico como una cadena.
idealmente, me gustaría escribir mi useState para que espere que el correo electrónico sea una cadena o nulo si es posible. De momento lo hereda como único 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> } Se devuelve el siguiente error para la función setEmail ya que la string en el argumento de la función no es un tipo válido para el null especificado en 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; }Actualmente, el compilador de TypeScript cree que el tipo de email y password son null (y ningún otro valor). Puede resolver esto proporcionando un parámetro de tipo explícito a la llamada useState para que se sepa que los tipos de email y password son string o 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> }Esto ya se aborda en algunos puntos:
https://dev.to/busypeople/notas-sobre-mecanografiado-react-hooks-28j2
https://codewithstyle.info/Using-React-useState-hook-with-TypeScript/
TLDR: pase un argumento de tipo a setState cuando tenga un estado inicial vacío
p.ej:
const [email, setEmail] = useState<string>();puede usar tipos mapeados de TS para mejorar la legibilidad y preferir valores indefinidos sobre valores nulos
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> }