Skip to content

Conversation

@mfedderly
Copy link
Collaborator

@mfedderly mfedderly commented Dec 19, 2025

Related: #2982 #2981

import { geomReduce } from "@turf/meta";
import { geomReduce, featureEach } from "@turf/meta";

// would be in @turf/meta
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly just pay attention to the two function typings, not the one with the actual implementation itself

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reference from lib.es5.d.ts on how Array.prototype.reduce is typed. Note that you can either specify an initial value and deal in that type for the reduce callbacks, or you can omit it and you are forced to use the shape of whatever is in the array.

    /**
     * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
     * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.
     * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.
     */
    reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T;
    reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T;
    /**
     * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
     * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.
     * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.
     */
    reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U;

: T = initialValue as any;
featureEach(geojson, function (currentFeature, featureIndex) {
if (featureIndex === 0 && initialValue === undefined)
previousValue = currentFeature as any;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this is actually different from how Array.prototype.reduce works when you don't specify an initial value. Without an initial value, you need to set previousValue to the first feature, but then only iterate 1...n in the array.

I think in order to know whether or not we were passed an initial value, we need to use arguments.length to see if we got an explicit undefined for initialValue vs a parameter that wasn't specified at all.

featureIndex
) as any;
});
return previousValue as any;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made a bunch of sloppy as any casts inside here, but the implementation would need to change to match up with the new behaviors to align with Array.prototype.reduce anyhow. Obviously I'd try to avoid them in a final implementation.

@mfedderly mfedderly force-pushed the mf/featureReducerTypes branch from 17c1b2b to e607a4d Compare December 19, 2025 15:03
} = {
type: "FeatureCollection",
features: [feature],
};
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This bit is a little unfortunate. You cannot omit the explicit type definition here and use as const instead, because that marks the whole thing as readonly and breaks the typings of featureReduce. We should probably handle readonly inputs as well and just make the relevant things downstream of that also readonly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants