Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

936
Views
No se puede invocar un objeto que posiblemente sea 'indefinido'.ts(2722)

Tengo un componente de botón. Simplemente le paso solo un accesorio onClick de muchos accesorios opcionales que he definido:

 const Button = (props: ButtonProps) => { const handleClick: React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement> = e => { props.onClick(e); } return ( <StyledButton onClick={handleClick}> {props.children} </StyledButton> ); };

Entonces lo estoy usando así:

 <Button onClick={(e) => { console.log(e); }}>Click me!</Button>

Ahora, ¿cómo es posible que, según el error mencionado en cuestión, el objeto no esté definido? Claramente le estoy pasando la función y eso también según la definición de tipo. Entonces, le estoy pasando un objeto. ¡Suficientemente simple!

 ... onClick?: React.MouseEventHandler<HTMLElement> ...

Agregué algunos controles más estrictos en este proyecto recientemente y los más relevantes son:

 "strictFunctionTypes": true, "strictNullChecks": true

strict:true ya está presente, este error nunca ocurrió.

¿Cuál es el problema aquí?

Actualizar - Tipos agregados

 export interface IBaseButtonProps { type?: ButtonType; disabled?: boolean; size?: ButtonSize; block?: boolean; loading?: boolean | { delay?: number }; icon?: string; className?: string; prefixCls?: string; children?: React.ReactNode; } export type AnchorButtonProps = { href: string, target?: string, onClick: React.MouseEventHandler<HTMLElement> } & IBaseButtonProps & Omit<React.AnchorHTMLAttributes<any>, 'type' | 'onClick'>; export type NativeButtonProps = { onClick: React.MouseEventHandler<HTMLElement>, htmlType?: ButtonHTMLType } & IBaseButtonProps & Omit<React.ButtonHTMLAttributes<any>, 'type' | 'onClick'>; export type ButtonProps = Partial<AnchorButtonProps & NativeButtonProps>

Notas:

La posible solución es desestructurar los accesorios y agregar el accesorio predeterminado. O usa defaultProps de React. Pero no estoy seguro si debería requerir eso realmente con Typescript.

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

Con Typescript 3.7+, también puede usar el encadenamiento opcional para invocar el método prop opcional:

 const Button = (props: ButtonProps) => { const handleClick: React.MouseEventHandler< HTMLButtonElement | HTMLAnchorElement > = e => { props.onClick?.(e); // works }; };

Puede leer más sobre el uso de encadenamiento opcional: https://www.stefanjudis.com/today-i-learned/opcional-chaining-helps-to-avoid-undefined-is-not-a-function-exceptions/

over 4 years ago · Santiago Trujillo Report

0

Ahora, ¿cómo es posible que, según el error mencionado en cuestión, el objeto no esté definido? [sic]

El uso de Partial<T> alrededor export type ButtonProps = Partial<AnchorButtonProps & NativeButtonProps> hace que onClick sea opcional. Cuando usamos Partial<T> , todas las propiedades reciben el ? y por lo tanto se vuelven opcionales, lo que significa que todos ellos pueden ser indefinidos.

Hay dos enfoques para una solución: uno es mantener ButtonProps igual con onClick como opcional, y verificar que onClick esté definido antes de llamarlo (arreglo 1); el otro es cambiar ButtonProps para hacer onClick requerido (corrección 2 y 3).

Solución 1: onClick sigue siendo opcional

Use los ButtonProps que ya tiene y luego verifique que onClick esté definido antes de llamarlo. Esto es lo que hace antd en el código que vinculaste en los comentarios.

 const Button = (props: ButtonProps) => { const handleClick: React.MouseEventHandler< HTMLButtonElement | HTMLAnchorElement > = e => { if (props.onClick) props.onClick(e); // works }; };

Solución 2: onClick se vuelve obligatorio

Cambie ButtonProps al no aplicar Partial a NativeButtonProps :

 type ButtonProps1 = Partial<AnchorButtonProps> & NativeButtonProps; const Button1 = (props: ButtonProps1) => { const handleClick: React.MouseEventHandler< HTMLButtonElement | HTMLAnchorElement > = e => { props.onClick(e); // works }; };

Solución 3: onClick también se vuelve obligatorio

Defina un tipo RequireKeys , que le permite especificar las claves que no son opcionales.

 type RequireKeys<T, TNames extends keyof T> = T & { [P in keyof T]-?: P extends TNames ? T[P] : never }; type ButtonProps2 = RequireKeys<ButtonProps, "onClick">; const Button2 = (props: ButtonProps2) => { const handleClick: React.MouseEventHandler< HTMLButtonElement | HTMLAnchorElement > = e => { props.onClick(e); // works }; };

Las respuestas a Tipos asignados: eliminar el modificador opcional tienen más información sobre cómo RequireKeys<T> .

over 4 years ago · Santiago Trujillo Report

0

Solo una respuesta clara

if (props.onClick) props.onClick(e);

si está definiendo una función props y quiere que sea opcional, defínala como,

 export type ButtonProps = { function?: () => void; };

Explicación: si desea utilizar una función como accesorios, puede haber instancias en las que desee pasar esa función (como accesorios) y puede haber otras instancias en las que no desee pasarla.

por ejemplo,

Código común DONDE llamar al componente <Home/> , digamos index.ts/index.js

 function myfunction(){ //do something alert("hello") } return ( <> <Home myfunction={myfunction}/> //passing prop <Home/> // not passing </> )

En JS, home.js

 export default function Home({myfunction}) { const const1 = "Hello World" return ( //do something myfunction(); //IMPORTANT line ) }

Ahora, es casi equivalente en TS, home.ts

En TS, definimos tipos de todo. Entonces, en ese caso tenemos que definir el tipo de esta función myfunction también, que estamos pasando.

Entonces, para esta función, nos damos cuenta de que,

  • No recibe parámetros, por lo que () (paréntesis vacíos) es suficiente, si hay parámetros, también debemos definir tipos para ellos.
  • No devuelve nada, por lo que el tipo de retorno es void
 export type HomeProps = { myfunction?: () => void; }; export default function Home({ myfunction }: HomeProps) { const const1 = "Hello World" return ( //do something if (myfunction) myfunction(); //IMPORTANT line ) }

Pista: respuesta anterior

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!