Cannot invoke an object which is possibly 'undefined'.ts(2722)
Now how can as per the erro mentioned in question, object be possibly undefined? [sic]
The use of Partial<T>
around export type ButtonProps = Partial<AnchorButtonProps & NativeButtonProps>
causes onClick
to be optional. When we use Partial<T>
, all the properties receive the ?
and thus become optional, which means that all of them can be undefined.
There are two approached to a fix: one is to keep ButtonProps
the same with onClick
as optional, and to check that onClick
is defined before calling it (fix 1); the other is to change ButtonProps
to make onClick
required (fix 2 and 3).
Fix 1: onClick
remains optional
Use the ButtonProps
that you already have, and then check that onClick
is defined before calling it. This is what antd does in the code you linked in the comments.
const Button = (props: ButtonProps) => {
const handleClick: React.MouseEventHandler<
HTMLButtonElement | HTMLAnchorElement
> = e => {
if (props.onClick) props.onClick(e); // works
};
};
Fix 2: onClick
becomes required
Change ButtonProps
by not applying the Partial
to the NativeButtonProps
:
type ButtonProps1 = Partial<AnchorButtonProps> & NativeButtonProps;
const Button1 = (props: ButtonProps1) => {
const handleClick: React.MouseEventHandler<
HTMLButtonElement | HTMLAnchorElement
> = e => {
props.onClick(e); // works
};
};
Fix 3: onClick
becomes required too
Define a RequireKeys
type, which lets you to specify the keys that are not optional.
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
};
};
The answers to Mapped Types: removing optional modifier have more information about how I defined RequireKeys<T>
.