Don't understand TypeScript function signature with weird object type as param

Issue

I have the following function signature:

(JSX attribute) onScroll: ({ scrollOffset, scrollUpdateWasRequested }: {
    scrollDirection: string;
    scrollOffset: number;
    scrollUpdateWasRequested: boolean;
}) => void

I just can’t wrap my head around it. What I read is "onScroll is a function that returns nothing (void) and takes weird object-type-mix as param. Could somebody explaind this weird object-type-mix to me?

Function signature is from onScroll prop of react-virtualitzed AutoSizer btw.

Solution

It’s using parameter destructuring assignment. You can write a function like this in JavaScript:

function foo({ x, y }) {
    console.log(x.toUpperCase(), y.toFixed(2));
}
foo({ x: "hello", y: Math.PI }) // HELLO, 3.14

This unpacks the (anonymous) parameter into x and y variables inside the function body. TypeScript allows you to strongly type this by treating { x, y } as the name of the parameter which you annotate like a regular named parameter:

function foo({ x, y }: { x: string, y: number }) {
    console.log(x.toUpperCase(), y.toFixed(2));
}

Also note that you are not required to unpack every property in the passed-in parameter. If for some reason you wanted to force callers to include a property in the parameter that you don’t use, you can still do it by giving the annotated type that property:

function bar({ x, y }: { x: string, y: number, z: boolean }) {
    console.log(x.toUpperCase(), y.toFixed(2));
}
bar({ x: "hello", y: Math.PI, z: true }) // HELLO, 3.14

So bar() needs a parameter with x, y, and z properties of particular types, but the function implementation doesn’t actually care about z.


Therefore your onScroll function is equivalent to the following declaration:

declare const onScroll: (param: OnScrollParam) => void
type OnScrollParam = {
    scrollDirection: string;
    scrollOffset: number;
    scrollUpdateWasRequested: boolean;
}

Meaning that onScroll() takes a single parameter of type OnScrollParam, which requires that scrollDirection property, despite the fact that apparently the implementation doesn’t use it:

onScroll({
    scrollDirection: "",
    scrollOffset: 1,
    scrollUpdateWasRequested: false
}); // okay

onScroll({
    scrollOffset: 1,
    scrollUpdateWasRequested: false
}); // error! Property 'scrollDirection' is missing 

Playground link to code

Answered By – jcalz

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published