Lunster
Lunster

Reputation: 906

TypeScript React event handler error; type is not assignable to type (union)

Using [email protected] with TypeScript what would be the correct implementation of the onScroll event?

Edit: I suspect there's some kind of namespace conflict happening between TypeScript's general definition for onScroll and the plugin; finding references for onScroll has two results, which reflects the error given at the bottom of this question, specifically not assignable to type '((event: UIEvent<HTMLElement>) => void) & ((scrollValues: ScrollValues, prevScrollValues: ScrollValues) => void)

I don't really understand what the & in that type means, does it mean it's expecting some kind of union of two functions, how does that work, do I pass in all possible arguments?

This is what I have now:

import * as React from "react";
import { Scrollbar } from 'react-scrollbars-custom';

export default class App extends React.Component  {

    handleScroll = (scrollValues : ScrollValues, prevScrollValues : ScrollValues)  => {
        // ...      
    }

    render() {

        return <Scrollbar onScroll={this.handleScroll} style={{ position: "absolute", height:"100%", width:"100%" }}>
        // ...
        </Scrollbar>
    }   
}

This is the error message:

Error TS2322 (TS) Type '(scrollValues: ScrollValues, prevScrollValues: ScrollValues) => void' is not assignable to type '((event: UIEvent<HTMLElement>) => void) & ((scrollValues: ScrollValues, prevScrollValues: ScrollValues) => void)'. Type '(scrollValues: ScrollValues, prevScrollValues: ScrollValues) => void' is not assignable to type '(event: UIEvent<HTMLElement>) => void'

Upvotes: 1

Views: 1540

Answers (2)

jaws
jaws

Reputation: 2022

As you suspect, the intersection type comes from an overloaded definition for onScroll. There is a collision between react-scrollbars-custom and React's own definition from @types/react. Paraphrasing a bit, you can see how this happens:

type ScrollbarProps = ElementProps & {
 onScroll?: (scrollValues: ScrollValues, prevScrollValues: ScrollValues) => void;
}

Jumping through a few interfaces, ElementProps eventually gets its onScroll property from DOMAttributes, in @types/react:

interface DOMAttributes<T> {
 onScroll?: UIEventHandler<T>;
}

The type really shouldn't be defined this way. But, here is one option for you to stay on the later version while you wait for this to get cleared up. Note that this is only side-stepping the issue, and is only marginally better than a type of any[]:

private handleScroll = (...args: Array<ScrollValues | React.UIEvent<HTMLElement>>) => {
 const [scrollValues, prevScrollValues] = args as ScrollValues[];
};

Upvotes: 1

Lunster
Lunster

Reputation: 906

After much head-scratching, I think this is probably an issue with the latest version of this plugin, reverting to 3.1.5 is a workaround for now, but that is an entire major version behind. If anyone understands why this is happening please answer and I'll accept.

Upvotes: 0

Related Questions