Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

935
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda