I have some React+TypeScript code that makes use of a component from a third party library.
<ThirdPartyComponent onSelect={(value: any) => {...}} />
eslint-typescript is identifying this as an issue:
Unexpected any. Specify a different type. eslint(@typescript-eslint/no-explicit-any)
The type definition of the select handler uses any
:
export interface ThirdPartySelectCallback extends React.EventHandler<any> {
(value: any, e: React.SyntheticEvent<{}>): void;
}
What is the proper way to avoid this issue without disabling the eslint rule?
Changing the type to string
gives a different error:
<ThirdPartyComponent onSelect={(value: string, e: React.SyntheticEvent<{}>) => {...}} />
Type '(value: string, e: SyntheticEvent<{}, Event>) => void' is not assignable to type 'ThirdPartySelectCallback'
You can use ThirdPartyComponent
like this:
// add the 2nd parameter e?: React.SyntheticEvent<{}>
const App = () => (
<ThirdPartyComponent
onSelect={(v: string, e?: React.SyntheticEvent<{}>) => {}}
/>
)
const ThirdPartyComponent = (props: { onSelect: ThirdPartySelectCallback }) => (
<div>Hello package</div>
)
React.EventHandler<any>
as well as ThirdPartySelectCallback
are function type interfaces. When one function interface extends another, for each function parameter the union of the types is formed (because function types are contravariant in their parameters). Have a look at this Playground for an easy example of this merging.
So let's take your example again:
// React.EventHandler - eased up a bit here
type EventHandler<E extends SyntheticEvent<any>> = (event: E): void
interface ThirdPartySelectCallback extends React.EventHandler<any> {
(value: any, e: React.SyntheticEvent<{}>): void;
}
E
and any
. E
| any
becomes effectively any
.undefined
(first function has no second parameter) and React.SyntheticEvent<{}>
, so its merged to React.SyntheticEvent<{}> | undefined
. So in the end, you can specify the following function for ThirdPartySelectCallback
:
(v: any, e?: React.SyntheticEvent<{}>) => void
, where v
can be literally of any type like string
to solve your eslint error.