Estoy aprendiendo TypeScipt y ya logré llegar a un callejón sin salida y TS no me deja ir más allá. Así que he definido mis interfaces de la siguiente manera:
export interface Test { id: number; date: Date; location: string; elements?: Element[]; } export interface Element { id: string; name: string; referenceFrom: number | string; referenceTo: number | string; result: number | string; }Luego estoy usando una de las interfaces para el enlace useState a continuación:
const [currentTest, setCurrentTest] = useState<Test | null>(null); Y en un momento estoy tratando de usar setCurrentTest y prevState dentro de él, sin embargo, TypeScript no me deja hacer eso y obtengo el siguiente error:
Argument of type '(prev: Test | null) => { elements: any[]; id?: number | undefined; date?: Date | undefined; location?: string | undefined; }' is not assignable to parameter of type 'SetStateAction<Test | null>'. Type '(prev: Test | null) => { elements: any[]; id?: number | undefined; date?: Date | undefined; location?: string | undefined; }' is not assignable to type '(prevState: Test | null) => Test | null'. Call signature return types '{ elements: any[]; id?: number | undefined; date?: Date | undefined; location?: string | undefined; }' and 'Test | null' are incompatible. The types of 'id' are incompatible between these types. Type 'number | undefined' is not assignable to type 'number'. Type 'undefined' is not assignable to type 'number'.ts(2345) La función en la que estoy usando este setCurrentTest se ve así:
const handleSubmitForm = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); const { id, name } = results; const referenceFrom = Number(results.referenceFrom); const referenceTo = Number(results.referenceTo); const result = Number(results.result); if ( id && name && referenceFrom > 0 && referenceTo > 0 && referenceFrom < referenceTo && result > 0 ) { setCurrentTest((prev) => ({...prev, elements: [...prev.elements, { id, name, referenceFrom, referenceTo, result }] })); } }; Lo que entiendo de esto es que el null opcional en Test | null está causando este problema. ¿También en el interface Element hay estos elements? que también está causando el problema porque también puede ser undefined .
Entonces, ¿cómo puedo escapar de esto?
Si no puede agregar un estado inicial para evitar tener el nulo, puede hacer una validación para que solo intente difundir el estado anterior si no es nulo. Como esto:
setCurrentTest((prev: any) => { if (prev) { return {...prev, elements: [...prev.elements, {id, name, referenceFrom, referenceTo, result}]}; } return {elements: [{id, name, referenceFrom, referenceTo, result}]}; });