Tengo esta interfaz.
interface parts { general: boolean, source: boolean, target: boolean }
Cuando se inicia el estado en el componente principal y se escribe con esa interfaz, TypeScript funciona como se esperaba.
const Parent: React.FC = () => { const [parts, setParts] = useState<parts>({ general: false, source: false, target: false, wrongKey: "Typescript reports problem" }) return ( <Child setParts={setParts} /> ) }
Pero cuando pasa a child, TypeScript no funciona como se esperaba.
const Child: React.FC<{setParts: React.Dispatch<React.SetStateAction<parts>> }> =({setParts}) => { setParts((parts: parts) => { ...parts, wrongKey: "Typescript doesn't report problem" }) return ( <div></div> ) }
Con tipos, como boolean o string, funciona como debería, pero hay algún problema con el diccionario.
La verificación de propiedad en exceso solo se activa cuando intenta asignar un objeto literal. Para otros casos, TypeScript solo verifica si la forma del objeto coincide con el tipo solicitado. El razonamiento es que lo más probable es que se trate de un error del desarrollador cuando pasa un objeto con forma incorrecta en línea. ¿Cuál podría ser el beneficio de permitir eso? Así que es un error tipográfico o quieres algo más.
Pero si pasa una variable, solo tiene que verificar si la forma está bien, no puede haber realmente ningún problema de tiempo de ejecución. Puedes hacer, por ejemplo, lo siguiente:
const [parts, setParts] = useState<parts>({ general: false, source: false, target: false, wrongKey: "Typescript reports problem" } as parts)
De esa manera, TypeScript se asegurará de pasar 'algo' que pueda tener forma de parts
. No sé si es útil, aunque, considérelo solo como un ejemplo :)
No estoy seguro de si esto es realmente un problema del que no está al tanto acerca de pasar una propiedad extraña. Me gustaría enfatizar que si olvidó pasar una propiedad para satisfacer la forma del tipo requerido, TypeScript le dirá eso, y eso es lo importante.
Si realmente desea negar propiedades adicionales, verifique esta respuesta: ¿Es posible restringir el objeto TypeScript para que contenga solo propiedades definidas por su clase?
ACTUALIZACIÓN 1: Por qué no se activa la verificación de propiedad en exceso, ya que en realidad regresamos con un objeto literal y dije que se ejecuta la verificación de propiedad en exceso en esos casos, esto es una especie de contradicción, pero en realidad no.
Considere este ejemplo:
type Parts = { general: boolean; source: boolean; target: boolean; } type FunctionType = (parts: Parts) => Parts; function ShowsError(parts: Parts): Parts { return { ...parts, someExtraPropertyWhichTriggerError:'Ooops' } } const myArrowFunction = (parts: Parts) => ({ ...parts, someExtraPropertyWithoutError:'Why no report?:(' }); const DoesntShowError: FunctionType = myArrowFunction;
Entonces, ¿qué está pasando allí? Parecen dos funciones idénticas, una es una flecha, una es normal, ¿por qué no hay error en el caso de la función de flecha? Mismos argumentos, mismo tipo de devolución, mismo objeto devuelto.
La diferencia clave es que cuando definimos nuestra función de flecha, su declaración de retorno NO está vinculada contextualmente a Partes. TypeScript no puede saber dónde se va a utilizar. Así que genera una forma para su tipo de retorno y continúa. Luego lo asignamos a DoesntShowError
, lo que requiere que asignemos una función con un tipo dado. Y la función de flecha satisface ese requisito. Eso es todo, creo, espero que ayude.