TypeScript React onScroll event handler error
gerainlotZS opened this issue · 3 comments
Using react-scrollbars-custom 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) => void) & ((scrollValues: ScrollValues, prevScrollValues: ScrollValues) => void)
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'
@gerainlotZS were you able to find a workaround for this?
Ok so I was able to figure out a TypeScript workaround for this:
First, you'll need to create a type predicate util to be able to distinguish between the UIEvent
and the actual ScrollState
function isScrollState(
eventOrState: React.UIEvent<HTMLDivElement, UIEvent> | ScrollbarState
): eventOrState is ScrollbarState {
return 'clientHeight' in eventOrState;
}
Second, define the actual onScroll
handler
function onScroll(
state: React.UIEvent<HTMLDivElement, UIEvent> | ScrollState,
prevState?: ScrollState
): void {
if (isScrollState(state)) {
// Can now use all of the properties of the ScrollState like scrollTop or clientWidth 👍
}
}
-- OR --
If you're using both the current and previous state you can use a function overload to match the props defined type better
function onScroll(event: React.UIEvent<HTMLDivElement, UIEvent>): void
function onScroll(state: ScrollState, prevState: ScrollState): void
function onScroll(
event: React.UIEvent<HTMLDivElement, UIEvent> | ScrollState,
prevState?: ScrollState
): void {
if (isScrollState(event) && prevState) {
// safely use event as ScrollState and prevState is defined as well
}
}
@brandonburrus Just a quick notification if someone runs into this one. It is ScrollState only, no ScrollbarState. They are completely different but they both exist.