diff --git a/packages/turf-meta/README.md b/packages/turf-meta/README.md index 95dc11e476..9a4bcf0721 100644 --- a/packages/turf-meta/README.md +++ b/packages/turf-meta/README.md @@ -16,7 +16,7 @@ Type: [Function][1] * `multiFeatureIndex` **[number][3]** The current index of the Multi-Feature being processed. * `geometryIndex` **[number][3]** The current index of the Geometry being processed. -Returns **void** +Returns **(void | `false`)** Return false to stop iterating ## coordEach @@ -122,7 +122,7 @@ Type: [Function][1] * `currentProperties` **[GeoJsonProperties][7]** The current Properties being processed. * `featureIndex` **[number][3]** The current index of the Feature being processed. -Returns **void** +Returns **(void | `false`)** Returning false to stop iterating ## propEach @@ -218,7 +218,7 @@ Type: [Function][1] * `currentFeature` **[Feature][7]\** The current Feature being processed. * `featureIndex` **[number][3]** The current index of the Feature being processed. -Returns **void** +Returns **(void | `false`)** Return false to stop iterating ## featureEach @@ -543,7 +543,7 @@ Type: [Function][1] * `geometryIndex` **[number][3]** The current index of the Geometry being processed. * `segmentIndex` **[number][3]** The current index of the Segment being processed. -Returns **void** +Returns **(void | `false`)** Return false to stop iterating ## segmentEach @@ -659,7 +659,7 @@ Type: [Function][1] * `multiFeatureIndex` **[number][3]** The current index of the Multi-Feature being processed * `geometryIndex` **[number][3]** The current index of the Geometry being processed -Returns **void** +Returns **(void | `false`)** Return false to stop iterating ## lineEach diff --git a/packages/turf-meta/bench.ts b/packages/turf-meta/bench.ts index 6601726853..eb47e6ff17 100644 --- a/packages/turf-meta/bench.ts +++ b/packages/turf-meta/bench.ts @@ -73,7 +73,7 @@ const suite = new Benchmark.Suite("turf-meta"); * findPoint - polygons x 2,160,583 ops/sec ±1.06% (87 runs sampled) */ Object.keys(fixtures).forEach((name) => { - const geojson = fixtures[name]; + const geojson = (fixtures as any)[name]; const noop = () => { /* no-op */ }; @@ -95,4 +95,4 @@ Object.keys(fixtures).forEach((name) => { .add("findPoint - " + name, () => meta.findPoint(geojson)); }); -suite.on("cycle", (e) => console.log(String(e.target))).run(); +suite.on("cycle", (e: any) => console.log(String(e.target))).run(); diff --git a/packages/turf-meta/index.d.ts b/packages/turf-meta/index.d.ts deleted file mode 100644 index 4fbab38490..0000000000 --- a/packages/turf-meta/index.d.ts +++ /dev/null @@ -1,336 +0,0 @@ -import { - Point, - LineString, - Polygon, - MultiLineString, - MultiPolygon, - FeatureCollection, - Feature, - Geometry, - GeometryObject, - GeometryCollection, - GeoJsonProperties, - BBox, -} from "geojson"; -import { AllGeoJSON, Lines, Id } from "@turf/helpers"; - -/** - * http://turfjs.org/docs/#coordreduce - */ -declare function coordReduce( - geojson: AllGeoJSON, - callback: ( - previousValue: Reducer, - currentCoord: number[], - coordIndex: number, - featureIndex: number, - multiFeatureIndex: number, - geometryIndex: number - ) => Reducer, - initialValue?: Reducer -): Reducer; - -/** - * http://turfjs.org/docs/#coordeach - */ -declare function coordEach( - geojson: AllGeoJSON, - callback: ( - currentCoord: number[], - coordIndex: number, - featureIndex: number, - multiFeatureIndex: number, - geometryIndex: number - ) => void, - excludeWrapCoord?: boolean -): void; - -/** - * http://turfjs.org/docs/#propeach - */ -declare function propEach( - geojson: Feature | FeatureCollection | Feature, - callback: (currentProperties: Props, featureIndex: number) => void -): void; - -/** - * http://turfjs.org/docs/#propreduce - */ -declare function propReduce< - Reducer, - P extends GeoJsonProperties = GeoJsonProperties, ->( - geojson: Feature | FeatureCollection | Geometry, - callback: ( - previousValue: Reducer, - currentProperties: P, - featureIndex: number - ) => Reducer, - initialValue?: Reducer -): Reducer; - -/** - * http://turfjs.org/docs/#featurereduce - */ -declare function featureReduce< - Reducer, - G extends GeometryObject, - P extends GeoJsonProperties = GeoJsonProperties, ->( - geojson: - | Feature - | FeatureCollection - | Feature, - callback: ( - previousValue: Reducer, - currentFeature: Feature, - featureIndex: number - ) => Reducer, - initialValue?: Reducer -): Reducer; - -/** - * http://turfjs.org/docs/#featureeach - */ -declare function featureEach< - G extends GeometryObject, - P extends GeoJsonProperties = GeoJsonProperties, ->( - geojson: - | Feature - | FeatureCollection - | Feature, - callback: (currentFeature: Feature, featureIndex: number) => void -): void; - -/** - * http://turfjs.org/docs/#coordall - */ -declare function coordAll(geojson: AllGeoJSON): number[][]; - -/** - * http://turfjs.org/docs/#geomreduce - */ -declare function geomReduce< - Reducer, - G extends GeometryObject, - P extends GeoJsonProperties = GeoJsonProperties, ->( - geojson: - | Feature - | FeatureCollection - | G - | GeometryCollection - | Feature, - callback: ( - previousValue: Reducer, - currentGeometry: G, - featureIndex: number, - featureProperties: P, - featureBBox: BBox, - featureId: Id - ) => Reducer, - initialValue?: Reducer -): Reducer; - -/** - * http://turfjs.org/docs/#geomeach - */ -declare function geomEach< - G extends GeometryObject | null, - P extends GeoJsonProperties = GeoJsonProperties, ->( - geojson: - | Feature - | FeatureCollection - | G - | GeometryCollection - | Feature, - callback: ( - currentGeometry: G, - featureIndex: number, - featureProperties: P, - featureBBox: BBox, - featureId: Id - ) => void -): void; - -/** - * http://turfjs.org/docs/#flattenreduce - */ -declare function flattenReduce< - Reducer, - G extends GeometryObject, - P extends GeoJsonProperties = GeoJsonProperties, ->( - geojson: - | Feature - | FeatureCollection - | G - | GeometryCollection - | Feature, - callback: ( - previousValue: Reducer, - currentFeature: Feature, - featureIndex: number, - multiFeatureIndex: number - ) => Reducer, - initialValue?: Reducer -): Reducer; - -/** - * http://turfjs.org/docs/#flatteneach - */ -declare function flattenEach< - G extends GeometryObject = GeometryObject, - P extends GeoJsonProperties = GeoJsonProperties, ->( - geojson: - | Feature - | FeatureCollection - | G - | GeometryCollection - | Feature, - callback: ( - currentFeature: Feature, - featureIndex: number, - multiFeatureIndex: number - ) => void -): void; - -/** - * http://turfjs.org/docs/#segmentreduce - */ -declare function segmentReduce< - Reducer, - P extends GeoJsonProperties = GeoJsonProperties, ->( - geojson: - | FeatureCollection - | Feature - | Lines - | Feature - | GeometryCollection, - callback: ( - previousValue?: Reducer, - currentSegment?: Feature, - featureIndex?: number, - multiFeatureIndex?: number, - segmentIndex?: number, - geometryIndex?: number - ) => Reducer, - initialValue?: Reducer -): Reducer; - -/** - * http://turfjs.org/docs/#segmenteach - */ -declare function segmentEach

( - geojson: AllGeoJSON, - callback: ( - currentSegment?: Feature, - featureIndex?: number, - multiFeatureIndex?: number, - segmentIndex?: number, - geometryIndex?: number - ) => void -): void; - -/** - * http://turfjs.org/docs/#linereduce - */ -declare function lineReduce< - Reducer, - P extends GeoJsonProperties = GeoJsonProperties, ->( - geojson: - | FeatureCollection - | Feature - | Lines - | Feature - | GeometryCollection, - callback: ( - previousValue?: Reducer, - currentLine?: Feature, - featureIndex?: number, - multiFeatureIndex?: number, - geometryIndex?: number - ) => Reducer, - initialValue?: Reducer -): Reducer; - -/** - * http://turfjs.org/docs/#lineeach - */ -declare function lineEach

( - geojson: - | FeatureCollection - | Feature - | Lines - | Feature - | GeometryCollection, - callback: ( - currentLine: Feature, - featureIndex?: number, - multiFeatureIndex?: number, - geometryIndex?: number - ) => void -): void; - -/** - * http://turfjs.org/docs/#findsegment - */ -declare function findSegment< - G extends LineString | MultiLineString | Polygon | MultiPolygon, - P extends GeoJsonProperties = GeoJsonProperties, ->( - geojson: Feature | FeatureCollection | G, - options?: { - featureIndex?: number; - multiFeatureIndex?: number; - geometryIndex?: number; - segmentIndex?: number; - properties?: P; - bbox?: BBox; - id?: Id; - } -): Feature; - -/** - * http://turfjs.org/docs/#findpoint - */ -declare function findPoint< - G extends GeometryObject, - P extends GeoJsonProperties = GeoJsonProperties, ->( - geojson: Feature | FeatureCollection | G, - options?: { - featureIndex?: number; - multiFeatureIndex?: number; - geometryIndex?: number; - coordIndex?: number; - properties?: P; - bbox?: BBox; - id?: Id; - } -): Feature; - -export { - coordReduce, - coordEach, - propEach, - propReduce, - featureReduce, - featureEach, - coordAll, - geomReduce, - geomEach, - flattenReduce, - flattenEach, - segmentReduce, - segmentEach, - lineReduce, - lineEach, - findSegment, - findPoint, -}; diff --git a/packages/turf-meta/index.js b/packages/turf-meta/index.ts similarity index 74% rename from packages/turf-meta/index.js rename to packages/turf-meta/index.ts index d1fe722c83..3ff482ef3e 100644 --- a/packages/turf-meta/index.js +++ b/packages/turf-meta/index.ts @@ -1,4 +1,27 @@ -import { feature, point, lineString, isObject } from "@turf/helpers"; +import { + feature, + point, + lineString, + isObject, + AllGeoJSON, + Id, + Lines, +} from "@turf/helpers"; +import { + BBox, + Feature, + FeatureCollection, + GeoJsonProperties, + Geometry, + GeometryCollection, + GeometryObject, + LineString, + MultiLineString, + MultiPoint, + MultiPolygon, + Point, + Polygon, +} from "geojson"; /** * Callback for coordEach @@ -9,7 +32,7 @@ import { feature, point, lineString, isObject } from "@turf/helpers"; * @param {number} featureIndex The current index of the Feature being processed. * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed. * @param {number} geometryIndex The current index of the Geometry being processed. - * @returns {void} + * @returns {void | false} Return false to stop iterating */ /** @@ -34,7 +57,17 @@ import { feature, point, lineString, isObject } from "@turf/helpers"; * //=geometryIndex * }); */ -function coordEach(geojson, callback, excludeWrapCoord) { +function coordEach( + geojson: AllGeoJSON, + callback: ( + currentCoord: number[], + coordIndex: number, + featureIndex: number, + multiFeatureIndex: number, + geometryIndex: number + ) => void | false, + excludeWrapCoord?: boolean +): void | false { // Handles null Geometry -- Skips this GeoJSON if (geojson === null) return; var j, @@ -50,7 +83,9 @@ function coordEach(geojson, callback, excludeWrapCoord) { type = geojson.type, isFeatureCollection = type === "FeatureCollection", isFeature = type === "Feature", - stop = isFeatureCollection ? geojson.features.length : 1; + stop = isFeatureCollection + ? (geojson as FeatureCollection).features.length + : 1; // This logic may look a little weird. The reason why it is that way // is because it's trying to be fast. GeoJSON supports multiple kinds @@ -66,27 +101,35 @@ function coordEach(geojson, callback, excludeWrapCoord) { // be required with the normalization approach. for (var featureIndex = 0; featureIndex < stop; featureIndex++) { geometryMaybeCollection = isFeatureCollection - ? geojson.features[featureIndex].geometry + ? (geojson as FeatureCollection).features[featureIndex].geometry : isFeature - ? geojson.geometry + ? (geojson as Feature).geometry : geojson; isGeometryCollection = geometryMaybeCollection ? geometryMaybeCollection.type === "GeometryCollection" : false; stopG = isGeometryCollection - ? geometryMaybeCollection.geometries.length + ? (geometryMaybeCollection as GeometryCollection).geometries.length : 1; for (var geomIndex = 0; geomIndex < stopG; geomIndex++) { var multiFeatureIndex = 0; var geometryIndex = 0; geometry = isGeometryCollection - ? geometryMaybeCollection.geometries[geomIndex] + ? (geometryMaybeCollection as GeometryCollection).geometries[geomIndex] : geometryMaybeCollection; // Handles null Geometry -- Skips this geometry if (geometry === null) continue; - coords = geometry.coordinates; + coords = ( + geometry as + | Point + | LineString + | Polygon + | MultiPoint + | MultiLineString + | MultiPolygon + ).coordinates; var geomType = geometry.type; wrapShrink = @@ -101,7 +144,7 @@ function coordEach(geojson, callback, excludeWrapCoord) { case "Point": if ( callback( - coords, + coords as Point["coordinates"], coordIndex, featureIndex, multiFeatureIndex, @@ -117,7 +160,11 @@ function coordEach(geojson, callback, excludeWrapCoord) { for (j = 0; j < coords.length; j++) { if ( callback( - coords[j], + ( + coords as + | LineString["coordinates"] + | MultiPoint["coordinates"] + )[j], coordIndex, featureIndex, multiFeatureIndex, @@ -132,11 +179,31 @@ function coordEach(geojson, callback, excludeWrapCoord) { break; case "Polygon": case "MultiLineString": - for (j = 0; j < coords.length; j++) { - for (k = 0; k < coords[j].length - wrapShrink; k++) { + for ( + j = 0; + j < + (coords as Polygon["coordinates"] | MultiLineString["coordinates"]) + .length; + j++ + ) { + for ( + k = 0; + k < + ( + coords as + | Polygon["coordinates"] + | MultiLineString["coordinates"] + )[j].length - + wrapShrink; + k++ + ) { if ( callback( - coords[j][k], + ( + coords as + | Polygon["coordinates"] + | MultiLineString["coordinates"] + )[j][k], coordIndex, featureIndex, multiFeatureIndex, @@ -152,13 +219,23 @@ function coordEach(geojson, callback, excludeWrapCoord) { if (geomType === "Polygon") multiFeatureIndex++; break; case "MultiPolygon": - for (j = 0; j < coords.length; j++) { + for (j = 0; j < (coords as MultiPolygon["coordinates"]).length; j++) { geometryIndex = 0; - for (k = 0; k < coords[j].length; k++) { - for (l = 0; l < coords[j][k].length - wrapShrink; l++) { + for ( + k = 0; + k < (coords as MultiPolygon["coordinates"])[j].length; + k++ + ) { + for ( + l = 0; + l < + (coords as MultiPolygon["coordinates"])[j][k].length - + wrapShrink; + l++ + ) { if ( callback( - coords[j][k][l], + (coords as MultiPolygon["coordinates"])[j][k][l], coordIndex, featureIndex, multiFeatureIndex, @@ -174,10 +251,17 @@ function coordEach(geojson, callback, excludeWrapCoord) { } break; case "GeometryCollection": - for (j = 0; j < geometry.geometries.length; j++) + for ( + j = 0; + j < (geometry as GeometryCollection).geometries.length; + j++ + ) if ( - coordEach(geometry.geometries[j], callback, excludeWrapCoord) === - false + coordEach( + (geometry as GeometryCollection).geometries[j], + callback, + excludeWrapCoord + ) === false ) return false; break; @@ -239,7 +323,19 @@ function coordEach(geojson, callback, excludeWrapCoord) { * return currentCoord; * }); */ -function coordReduce(geojson, callback, initialValue, excludeWrapCoord) { +function coordReduce( + geojson: AllGeoJSON, + callback: ( + previousValue: Reducer, + currentCoord: number[], + coordIndex: number, + featureIndex: number, + multiFeatureIndex: number, + geometryIndex: number + ) => Reducer, + initialValue?: Reducer, + excludeWrapCoord?: boolean +): Reducer { var previousValue = initialValue; coordEach( geojson, @@ -251,10 +347,10 @@ function coordReduce(geojson, callback, initialValue, excludeWrapCoord) { geometryIndex ) { if (coordIndex === 0 && initialValue === undefined) - previousValue = currentCoord; + previousValue = currentCoord as Reducer; else previousValue = callback( - previousValue, + previousValue as Reducer, currentCoord, coordIndex, featureIndex, @@ -264,7 +360,7 @@ function coordReduce(geojson, callback, initialValue, excludeWrapCoord) { }, excludeWrapCoord ); - return previousValue; + return previousValue as Reducer; } /** @@ -273,7 +369,7 @@ function coordReduce(geojson, callback, initialValue, excludeWrapCoord) { * @callback propEachCallback * @param {GeoJsonProperties} currentProperties The current Properties being processed. * @param {number} featureIndex The current index of the Feature being processed. - * @returns {void} + * @returns {void | false} Returning false to stop iterating */ /** @@ -294,16 +390,25 @@ function coordReduce(geojson, callback, initialValue, excludeWrapCoord) { * //=featureIndex * }); */ -function propEach(geojson, callback) { +function propEach( + geojson: Feature | FeatureCollection | Feature, + callback: (currentProperties: Props, featureIndex: number) => void | false +): void { var i; switch (geojson.type) { case "FeatureCollection": for (i = 0; i < geojson.features.length; i++) { - if (callback(geojson.features[i].properties, i) === false) break; + if ( + callback( + (geojson as FeatureCollection).features[i].properties as Props, + i + ) === false + ) + break; } break; case "Feature": - callback(geojson.properties, 0); + callback(geojson.properties as Props, 0); break; } } @@ -353,15 +458,30 @@ function propEach(geojson, callback) { * return currentProperties * }); */ -function propReduce(geojson, callback, initialValue) { +function propReduce( + geojson: Feature | FeatureCollection | Geometry, + callback: ( + previousValue: Reducer, + currentProperties: P, + featureIndex: number + ) => Reducer, + initialValue?: Reducer +): Reducer { var previousValue = initialValue; - propEach(geojson, function (currentProperties, featureIndex) { - if (featureIndex === 0 && initialValue === undefined) - previousValue = currentProperties; - else - previousValue = callback(previousValue, currentProperties, featureIndex); - }); - return previousValue; + propEach( + geojson as Feature | FeatureCollection, + function (currentProperties, featureIndex) { + if (featureIndex === 0 && initialValue === undefined) + previousValue = currentProperties as Reducer; + else + previousValue = callback( + previousValue as Reducer, + currentProperties as P, + featureIndex + ); + } + ); + return previousValue as Reducer; } /** @@ -370,7 +490,7 @@ function propReduce(geojson, callback, initialValue) { * @callback featureEachCallback * @param {Feature} currentFeature The current Feature being processed. * @param {number} featureIndex The current index of the Feature being processed. - * @returns {void} + * @returns {void | false} Return false to stop iterating */ /** @@ -392,12 +512,27 @@ function propReduce(geojson, callback, initialValue) { * //=featureIndex * }); */ -function featureEach(geojson, callback) { +function featureEach< + G extends GeometryObject, + P extends GeoJsonProperties = GeoJsonProperties, +>( + geojson: + | Feature + | FeatureCollection + | Feature, + callback: ( + currentFeature: Feature, + featureIndex: number + ) => void | false +): void { if (geojson.type === "Feature") { - callback(geojson, 0); + callback(geojson as Feature, 0); } else if (geojson.type === "FeatureCollection") { for (var i = 0; i < geojson.features.length; i++) { - if (callback(geojson.features[i], i) === false) break; + if ( + callback((geojson as FeatureCollection).features[i], i) === false + ) + break; } } } @@ -445,14 +580,34 @@ function featureEach(geojson, callback) { * return currentFeature * }); */ -function featureReduce(geojson, callback, initialValue) { +function featureReduce< + Reducer, + G extends GeometryObject, + P extends GeoJsonProperties = GeoJsonProperties, +>( + geojson: + | Feature + | FeatureCollection + | Feature, + callback: ( + previousValue: Reducer, + currentFeature: Feature, + featureIndex: number + ) => Reducer, + initialValue?: Reducer +): Reducer { var previousValue = initialValue; featureEach(geojson, function (currentFeature, featureIndex) { if (featureIndex === 0 && initialValue === undefined) - previousValue = currentFeature; - else previousValue = callback(previousValue, currentFeature, featureIndex); + previousValue = currentFeature as Reducer; + else + previousValue = callback( + previousValue as Reducer, + currentFeature, + featureIndex + ); }); - return previousValue; + return previousValue as Reducer; } /** @@ -470,8 +625,8 @@ function featureReduce(geojson, callback, initialValue) { * var coords = turf.coordAll(features); * //= [[26, 37], [36, 53]] */ -function coordAll(geojson) { - var coords = []; +function coordAll(geojson: AllGeoJSON): number[][] { + var coords: number[][] = []; coordEach(geojson, function (coord) { coords.push(coord); }); @@ -511,7 +666,24 @@ function coordAll(geojson) { * //=featureId * }); */ -function geomEach(geojson, callback) { +function geomEach< + G extends GeometryObject, + P extends GeoJsonProperties = GeoJsonProperties, +>( + geojson: + | Feature + | FeatureCollection + | G + | GeometryCollection + | Feature, + callback: ( + currentGeometry: G, + featureIndex: number, + featureProperties: P, + featureBBox: BBox | undefined, + featureId: Id | undefined + ) => void | false +): void | false { var i, j, g, @@ -525,7 +697,9 @@ function geomEach(geojson, callback) { featureIndex = 0, isFeatureCollection = geojson.type === "FeatureCollection", isFeature = geojson.type === "Feature", - stop = isFeatureCollection ? geojson.features.length : 1; + stop = isFeatureCollection + ? (geojson as FeatureCollection).features.length + : 1; // This logic may look a little weird. The reason why it is that way // is because it's trying to be fast. GeoJSON supports multiple kinds @@ -541,44 +715,44 @@ function geomEach(geojson, callback) { // be required with the normalization approach. for (i = 0; i < stop; i++) { geometryMaybeCollection = isFeatureCollection - ? geojson.features[i].geometry + ? (geojson as FeatureCollection).features[i].geometry : isFeature - ? geojson.geometry + ? (geojson as Feature).geometry : geojson; featureProperties = isFeatureCollection - ? geojson.features[i].properties + ? (geojson as FeatureCollection).features[i].properties : isFeature - ? geojson.properties + ? (geojson as Feature).properties : {}; featureBBox = isFeatureCollection - ? geojson.features[i].bbox + ? (geojson as FeatureCollection).features[i].bbox : isFeature ? geojson.bbox : undefined; featureId = isFeatureCollection - ? geojson.features[i].id + ? (geojson as FeatureCollection).features[i].id : isFeature - ? geojson.id + ? (geojson as Feature).id : undefined; isGeometryCollection = geometryMaybeCollection ? geometryMaybeCollection.type === "GeometryCollection" : false; stopG = isGeometryCollection - ? geometryMaybeCollection.geometries.length + ? (geometryMaybeCollection as GeometryCollection).geometries.length : 1; for (g = 0; g < stopG; g++) { geometry = isGeometryCollection - ? geometryMaybeCollection.geometries[g] + ? (geometryMaybeCollection as GeometryCollection).geometries[g] : geometryMaybeCollection; // Handle null Geometry if (geometry === null) { if ( callback( - null, + null as unknown as G, featureIndex, - featureProperties, + featureProperties as P, featureBBox, featureId ) === false @@ -595,9 +769,9 @@ function geomEach(geojson, callback) { case "MultiPolygon": { if ( callback( - geometry, + geometry as G, featureIndex, - featureProperties, + featureProperties as P, featureBBox, featureId ) === false @@ -609,9 +783,9 @@ function geomEach(geojson, callback) { for (j = 0; j < geometry.geometries.length; j++) { if ( callback( - geometry.geometries[j], + geometry.geometries[j] as G, featureIndex, - featureProperties, + featureProperties as P, featureBBox, featureId ) === false @@ -678,7 +852,27 @@ function geomEach(geojson, callback) { * return currentGeometry * }); */ -function geomReduce(geojson, callback, initialValue) { +function geomReduce< + Reducer, + G extends GeometryObject, + P extends GeoJsonProperties = GeoJsonProperties, +>( + geojson: + | Feature + | FeatureCollection + | G + | GeometryCollection + | Feature, + callback: ( + previousValue: Reducer, + currentGeometry: G, + featureIndex: number, + featureProperties: P, + featureBBox: BBox | undefined, + featureId: Id | undefined + ) => Reducer, + initialValue?: Reducer +): Reducer { var previousValue = initialValue; geomEach( geojson, @@ -690,10 +884,10 @@ function geomReduce(geojson, callback, initialValue) { featureId ) { if (featureIndex === 0 && initialValue === undefined) - previousValue = currentGeometry; + previousValue = currentGeometry as unknown as Reducer; else previousValue = callback( - previousValue, + previousValue as Reducer, currentGeometry, featureIndex, featureProperties, @@ -702,7 +896,7 @@ function geomReduce(geojson, callback, initialValue) { ); } ); - return previousValue; + return previousValue as Reducer; } /** @@ -735,7 +929,22 @@ function geomReduce(geojson, callback, initialValue) { * //=multiFeatureIndex * }); */ -function flattenEach(geojson, callback) { +function flattenEach< + G extends GeometryObject = GeometryObject, + P extends GeoJsonProperties = GeoJsonProperties, +>( + geojson: + | Feature + | FeatureCollection + | G + | GeometryCollection + | Feature, + callback: ( + currentFeature: Feature, + featureIndex: number, + multiFeatureIndex: number + ) => void | boolean +): void { geomEach(geojson, function (geometry, featureIndex, properties, bbox, id) { // Callback for single geometry var type = geometry === null ? null : geometry.type; @@ -772,17 +981,26 @@ function flattenEach(geojson, callback) { for ( var multiFeatureIndex = 0; - multiFeatureIndex < geometry.coordinates.length; + multiFeatureIndex < + (geometry as MultiPoint | MultiLineString | MultiPolygon).coordinates + .length; multiFeatureIndex++ ) { - var coordinate = geometry.coordinates[multiFeatureIndex]; + var coordinate = (geometry as MultiPoint | MultiLineString | MultiPolygon) + .coordinates[multiFeatureIndex]; var geom = { type: geomType, coordinates: coordinate, }; if ( - callback(feature(geom, properties), featureIndex, multiFeatureIndex) === - false + callback( + feature(geom as Point | LineString | Polygon, properties) as Feature< + G, + P + >, + featureIndex, + multiFeatureIndex + ) === false ) return false; } @@ -834,7 +1052,25 @@ function flattenEach(geojson, callback) { * return currentFeature * }); */ -function flattenReduce(geojson, callback, initialValue) { +function flattenReduce< + Reducer, + G extends GeometryObject, + P extends GeoJsonProperties = GeoJsonProperties, +>( + geojson: + | Feature + | FeatureCollection + | G + | GeometryCollection + | Feature, + callback: ( + previousValue: Reducer, + currentFeature: Feature, + featureIndex: number, + multiFeatureIndex: number + ) => Reducer, + initialValue?: Reducer +): Reducer { var previousValue = initialValue; flattenEach( geojson, @@ -844,17 +1080,17 @@ function flattenReduce(geojson, callback, initialValue) { multiFeatureIndex === 0 && initialValue === undefined ) - previousValue = currentFeature; + previousValue = currentFeature as Reducer; else previousValue = callback( - previousValue, + previousValue as Reducer, currentFeature, featureIndex, multiFeatureIndex ); } ); - return previousValue; + return previousValue as Reducer; } /** @@ -866,7 +1102,7 @@ function flattenReduce(geojson, callback, initialValue) { * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed. * @param {number} geometryIndex The current index of the Geometry being processed. * @param {number} segmentIndex The current index of the Segment being processed. - * @returns {void} + * @returns {void | false} Return false to stop iterating */ /** @@ -894,7 +1130,16 @@ function flattenReduce(geojson, callback, initialValue) { * total++; * }); */ -function segmentEach(geojson, callback) { +function segmentEach

( + geojson: AllGeoJSON, + callback: ( + currentSegment: Feature, + featureIndex?: number, + multiFeatureIndex?: number, + segmentIndex?: number, + geometryIndex?: number + ) => void | boolean +): void { flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) { var segmentIndex = 0; @@ -905,7 +1150,7 @@ function segmentEach(geojson, callback) { if (type === "Point" || type === "MultiPoint") return; // Generate 2-vertex line segments - var previousCoords; + var previousCoords: number[]; var previousFeatureIndex = 0; var previousMultiIndex = 0; var prevGeomIndex = 0; @@ -939,7 +1184,7 @@ function segmentEach(geojson, callback) { ); if ( callback( - currentSegment, + currentSegment as Feature, featureIndex, multiFeatureIndex, geometryIndex, @@ -1010,7 +1255,26 @@ function segmentEach(geojson, callback) { * return previousValue; * }, initialValue); */ -function segmentReduce(geojson, callback, initialValue) { +function segmentReduce< + Reducer, + P extends GeoJsonProperties = GeoJsonProperties, +>( + geojson: + | FeatureCollection + | Feature + | Lines + | Feature + | GeometryCollection, + callback: ( + previousValue: Reducer, + currentSegment: Feature, + featureIndex?: number, + multiFeatureIndex?: number, + segmentIndex?: number, + geometryIndex?: number + ) => Reducer, + initialValue?: Reducer +): Reducer { var previousValue = initialValue; var started = false; segmentEach( @@ -1023,11 +1287,11 @@ function segmentReduce(geojson, callback, initialValue) { segmentIndex ) { if (started === false && initialValue === undefined) - previousValue = currentSegment; + previousValue = currentSegment as Reducer; else previousValue = callback( - previousValue, - currentSegment, + previousValue as Reducer, + currentSegment as Feature, featureIndex, multiFeatureIndex, geometryIndex, @@ -1036,7 +1300,7 @@ function segmentReduce(geojson, callback, initialValue) { started = true; } ); - return previousValue; + return previousValue as Reducer; } /** @@ -1047,7 +1311,7 @@ function segmentReduce(geojson, callback, initialValue) { * @param {number} featureIndex The current index of the Feature being processed * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed * @param {number} geometryIndex The current index of the Geometry being processed - * @returns {void} + * @returns {void | false} Return false to stop iterating */ /** @@ -1071,7 +1335,20 @@ function segmentReduce(geojson, callback, initialValue) { * //=geometryIndex * }); */ -function lineEach(geojson, callback) { +function lineEach

( + geojson: + | FeatureCollection + | Feature + | Lines + | Feature + | GeometryCollection, + callback: ( + currentLine: Feature, + featureIndex?: number, + multiFeatureIndex?: number, + geometryIndex?: number + ) => void | false +): void { // validation if (!geojson) throw new Error("geojson is required"); @@ -1081,7 +1358,14 @@ function lineEach(geojson, callback) { var coords = feature.geometry.coordinates; switch (type) { case "LineString": - if (callback(feature, featureIndex, multiFeatureIndex, 0, 0) === false) + if ( + callback( + feature as Feature, + featureIndex, + multiFeatureIndex, + 0 + ) === false + ) return false; break; case "Polygon": @@ -1092,7 +1376,10 @@ function lineEach(geojson, callback) { ) { if ( callback( - lineString(coords[geometryIndex], feature.properties), + lineString( + (coords as Polygon["coordinates"])[geometryIndex], + feature.properties + ), featureIndex, multiFeatureIndex, geometryIndex @@ -1152,13 +1439,28 @@ function lineEach(geojson, callback) { * return currentLine * }); */ -function lineReduce(geojson, callback, initialValue) { +function lineReduce( + geojson: + | FeatureCollection + | Feature + | Lines + | Feature + | GeometryCollection, + callback: ( + previousValue?: Reducer, + currentLine?: Feature, + featureIndex?: number, + multiFeatureIndex?: number, + geometryIndex?: number + ) => Reducer, + initialValue?: Reducer +): Reducer { var previousValue = initialValue; lineEach( geojson, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) { if (featureIndex === 0 && initialValue === undefined) - previousValue = currentLine; + previousValue = currentLine as Reducer; else previousValue = callback( previousValue, @@ -1169,7 +1471,7 @@ function lineReduce(geojson, callback, initialValue) { ); } ); - return previousValue; + return previousValue as Reducer; } /** @@ -1206,7 +1508,21 @@ function lineReduce(geojson, callback, initialValue) { * turf.findSegment(multiLine, {multiFeatureIndex: -1, segmentIndex: -1}); * // => Feature> */ -function findSegment(geojson, options) { +function findSegment< + G extends LineString | MultiLineString | Polygon | MultiPolygon, + P extends GeoJsonProperties = GeoJsonProperties, +>( + geojson: Feature | FeatureCollection | G, + options?: { + featureIndex?: number; + multiFeatureIndex?: number; + geometryIndex?: number; + segmentIndex?: number; + properties?: P; + bbox?: BBox; + id?: Id; + } +): Feature { // Optional Parameters options = options || {}; if (!isObject(options)) throw new Error("options is invalid"); @@ -1230,9 +1546,9 @@ function findSegment(geojson, options) { properties = properties || geojson.properties; geometry = geojson.geometry; break; - case "Point": - case "MultiPoint": - return null; + case "Point" as any: + case "MultiPoint" as any: + return null as any; case "LineString": case "Polygon": case "MultiLineString": @@ -1244,16 +1560,19 @@ function findSegment(geojson, options) { } // Find SegmentIndex - if (geometry === null) return null; + if (geometry === null) return null as any; var coords = geometry.coordinates; switch (geometry.type) { - case "Point": - case "MultiPoint": - return null; + case "Point" as any: + case "MultiPoint" as any: + return null as any; case "LineString": if (segmentIndex < 0) segmentIndex = coords.length + segmentIndex - 1; return lineString( - [coords[segmentIndex], coords[segmentIndex + 1]], + [ + (coords as LineString["coordinates"])[segmentIndex], + (coords as LineString["coordinates"])[segmentIndex + 1], + ], properties, options ); @@ -1263,8 +1582,8 @@ function findSegment(geojson, options) { segmentIndex = coords[geometryIndex].length + segmentIndex - 1; return lineString( [ - coords[geometryIndex][segmentIndex], - coords[geometryIndex][segmentIndex + 1], + (coords as Polygon["coordinates"])[geometryIndex][segmentIndex], + (coords as Polygon["coordinates"])[geometryIndex][segmentIndex + 1], ], properties, options @@ -1276,8 +1595,12 @@ function findSegment(geojson, options) { segmentIndex = coords[multiFeatureIndex].length + segmentIndex - 1; return lineString( [ - coords[multiFeatureIndex][segmentIndex], - coords[multiFeatureIndex][segmentIndex + 1], + (coords as MultiLineString["coordinates"])[multiFeatureIndex][ + segmentIndex + ], + (coords as MultiLineString["coordinates"])[multiFeatureIndex][ + segmentIndex + 1 + ], ], properties, options @@ -1289,11 +1612,19 @@ function findSegment(geojson, options) { geometryIndex = coords[multiFeatureIndex].length + geometryIndex; if (segmentIndex < 0) segmentIndex = - coords[multiFeatureIndex][geometryIndex].length - segmentIndex - 1; + (coords as MultiPolygon["coordinates"])[multiFeatureIndex][ + geometryIndex + ].length - + segmentIndex - + 1; return lineString( [ - coords[multiFeatureIndex][geometryIndex][segmentIndex], - coords[multiFeatureIndex][geometryIndex][segmentIndex + 1], + (coords as MultiPolygon["coordinates"])[multiFeatureIndex][ + geometryIndex + ][segmentIndex], + (coords as MultiPolygon["coordinates"])[multiFeatureIndex][ + geometryIndex + ][segmentIndex + 1], ], properties, options @@ -1335,7 +1666,21 @@ function findSegment(geojson, options) { * turf.findPoint(multiLine, {multiFeatureIndex: -1, coordIndex: -1}); * // => Feature> */ -function findPoint(geojson, options) { +function findPoint< + G extends GeometryObject, + P extends GeoJsonProperties = GeoJsonProperties, +>( + geojson: Feature | FeatureCollection | G, + options?: { + featureIndex?: number; + multiFeatureIndex?: number; + geometryIndex?: number; + coordIndex?: number; + properties?: P; + bbox?: BBox; + id?: Id; + } +): Feature { // Optional Parameters options = options || {}; if (!isObject(options)) throw new Error("options is invalid"); @@ -1361,7 +1706,7 @@ function findPoint(geojson, options) { break; case "Point": case "MultiPoint": - return null; + return null as any; case "LineString": case "Polygon": case "MultiLineString": @@ -1373,39 +1718,74 @@ function findPoint(geojson, options) { } // Find Coord Index - if (geometry === null) return null; - var coords = geometry.coordinates; + if (geometry === null) return null as any; + var coords = ( + geometry as + | Point + | LineString + | Polygon + | MultiPoint + | MultiLineString + | MultiPolygon + ).coordinates; switch (geometry.type) { case "Point": - return point(coords, properties, options); + return point(coords as Point["coordinates"], properties, options); case "MultiPoint": if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex; - return point(coords[multiFeatureIndex], properties, options); + return point( + (coords as MultiPoint["coordinates"])[multiFeatureIndex], + properties, + options + ); case "LineString": if (coordIndex < 0) coordIndex = coords.length + coordIndex; - return point(coords[coordIndex], properties, options); + return point( + (coords as LineString["coordinates"])[coordIndex], + properties, + options + ); case "Polygon": if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex; if (coordIndex < 0) - coordIndex = coords[geometryIndex].length + coordIndex; - return point(coords[geometryIndex][coordIndex], properties, options); + coordIndex = + (coords as Polygon["coordinates"])[geometryIndex].length + coordIndex; + return point( + (coords as Polygon["coordinates"])[geometryIndex][coordIndex], + properties, + options + ); case "MultiLineString": if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex; if (coordIndex < 0) - coordIndex = coords[multiFeatureIndex].length + coordIndex; - return point(coords[multiFeatureIndex][coordIndex], properties, options); + coordIndex = + (coords as MultiLineString["coordinates"])[multiFeatureIndex].length + + coordIndex; + return point( + (coords as MultiLineString["coordinates"])[multiFeatureIndex][ + coordIndex + ], + properties, + options + ); case "MultiPolygon": if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex; if (geometryIndex < 0) - geometryIndex = coords[multiFeatureIndex].length + geometryIndex; + geometryIndex = + (coords as MultiPolygon["coordinates"])[multiFeatureIndex].length + + geometryIndex; if (coordIndex < 0) coordIndex = - coords[multiFeatureIndex][geometryIndex].length - coordIndex; + (coords as MultiPolygon["coordinates"])[multiFeatureIndex][ + geometryIndex + ].length - coordIndex; return point( - coords[multiFeatureIndex][geometryIndex][coordIndex], + (coords as MultiPolygon["coordinates"])[multiFeatureIndex][ + geometryIndex + ][coordIndex], properties, options ); diff --git a/packages/turf-meta/package.json b/packages/turf-meta/package.json index 1ccf7021b6..c02c8396d1 100644 --- a/packages/turf-meta/package.json +++ b/packages/turf-meta/package.json @@ -75,13 +75,16 @@ "devDependencies": { "@turf/random": "workspace:*", "@types/benchmark": "^2.1.5", + "@types/tape": "^5.8.1", "benchmark": "^2.1.4", "tape": "^5.9.0", "tsup": "^8.4.0", - "tsx": "^4.19.4" + "tsx": "^4.19.4", + "typescript": "^5.8.3" }, "dependencies": { "@turf/helpers": "workspace:*", - "@types/geojson": "^7946.0.10" + "@types/geojson": "^7946.0.10", + "tslib": "^2.8.1" } } diff --git a/packages/turf-meta/test.ts b/packages/turf-meta/test.ts index 8c59c0e0bd..05fea0c6d1 100644 --- a/packages/turf-meta/test.ts +++ b/packages/turf-meta/test.ts @@ -10,8 +10,22 @@ import { geometryCollection, featureCollection, lineStrings, + Lines, } from "@turf/helpers"; import * as meta from "./index.js"; +import { + BBox, + Feature, + FeatureCollection, + Geometry, + LineString, + MultiLineString, + MultiPoint, + MultiPolygon, + Point, + Polygon, + Position, +} from "geojson"; const pt = point([0, 0], { a: 1 }); const pt2 = point([1, 1]); @@ -80,7 +94,7 @@ const geomCollection = geometryCollection( { a: 0 } ); const fcNull = featureCollection([feature(null), feature(null)]); -const fcMixed = featureCollection([ +const fcMixed = featureCollection([ point([0, 0]), lineString([ [1, 1], @@ -98,8 +112,10 @@ const fcMixed = featureCollection([ ]), ]); -function collection(feature) { - const featureCollection = { +function collection( + feature: Feature +): [Feature, FeatureCollection] { + const featureCollection: FeatureCollection = { type: "FeatureCollection", features: [feature], }; @@ -107,14 +123,16 @@ function collection(feature) { return [feature, featureCollection]; } -function featureAndCollection(geometry) { - const feature = { +function featureAndCollection( + geometry: G +): [G, Feature, FeatureCollection] { + const feature: Feature = { type: "Feature", geometry: geometry, properties: { a: 1 }, }; - const featureCollection = { + const featureCollection: FeatureCollection = { type: "FeatureCollection", features: [feature], }; @@ -144,7 +162,7 @@ test("coordEach -- Point", (t) => { test("coordEach -- LineString", (t) => { featureAndCollection(line.geometry).forEach((input) => { - const output = []; + const output: Position[] = []; let lastIndex; meta.coordEach(input, (coord, index) => { output.push(coord); @@ -161,7 +179,7 @@ test("coordEach -- LineString", (t) => { test("coordEach -- Polygon", (t) => { featureAndCollection(poly.geometry).forEach((input) => { - const output = []; + const output: Position[] = []; let lastIndex; meta.coordEach(input, (coord, index) => { output.push(coord); @@ -197,9 +215,9 @@ test("coordEach -- Polygon excludeWrapCoord", (t) => { test("coordEach -- MultiPolygon", (t) => { const coords = []; - const coordIndexes = []; - const featureIndexes = []; - const multiFeatureIndexes = []; + const coordIndexes: number[] = []; + const featureIndexes: number[] = []; + const multiFeatureIndexes: number[] = []; meta.coordEach( multiPoly, (coord, coordIndex, featureIndex, multiFeatureIndex) => { @@ -218,9 +236,9 @@ test("coordEach -- MultiPolygon", (t) => { test("coordEach -- FeatureCollection", (t) => { const coords = []; - const coordIndexes = []; - const featureIndexes = []; - const multiFeatureIndexes = []; + const coordIndexes: number[] = []; + const featureIndexes: number[] = []; + const multiFeatureIndexes: number[] = []; meta.coordEach( fcMixed, (coord, coordIndex, featureIndex, multiFeatureIndex) => { @@ -333,7 +351,7 @@ test("Array.reduce() -- previous-coordinates+initialValue", (t) => { lastIndex = index; coords.push(currentCoords); return currentCoords; - }, line[0]); + }, undefined as any); t.equal(lastIndex, 1); t.equal(coords.length, 2); t.end(); @@ -341,14 +359,14 @@ test("Array.reduce() -- previous-coordinates+initialValue", (t) => { test("unknown", (t) => { t.throws(function () { - meta.coordEach({}); + meta.coordEach({} as any, () => undefined); }); t.end(); }); test("geomEach -- GeometryCollection", (t) => { featureAndCollection(geomCollection.geometry).forEach((input) => { - const output = []; + const output: Geometry[] = []; meta.geomEach(input, (geom) => { output.push(geom); }); @@ -358,7 +376,7 @@ test("geomEach -- GeometryCollection", (t) => { }); test("geomEach -- bare-GeometryCollection", (t) => { - const output = []; + const output: Geometry[] = []; meta.geomEach(geomCollection, (geom) => { output.push(geom); }); @@ -367,7 +385,7 @@ test("geomEach -- bare-GeometryCollection", (t) => { }); test("geomEach -- bare-pointGeometry", (t) => { - const output = []; + const output: Point[] = []; meta.geomEach(pt.geometry, (geom) => { output.push(geom); }); @@ -376,7 +394,7 @@ test("geomEach -- bare-pointGeometry", (t) => { }); test("geomEach -- bare-pointFeature", (t) => { - const output = []; + const output: Point[] = []; meta.geomEach(pt, (geom) => { output.push(geom); }); @@ -395,7 +413,7 @@ test("geomEach -- multiGeometryFeature-properties", (t) => { test("flattenEach -- MultiPoint", (t) => { featureAndCollection(multiPt.geometry).forEach((input) => { - const output = []; + const output: MultiPoint[] = []; // this is actually Point[] but flattenEach's types are bad meta.flattenEach(input, (feature) => { output.push(feature.geometry); }); @@ -406,8 +424,8 @@ test("flattenEach -- MultiPoint", (t) => { test("flattenEach -- Mixed FeatureCollection", (t) => { const features = []; - const featureIndexes = []; - const multiFeatureIndexes = []; + const featureIndexes: number[] = []; + const multiFeatureIndexes: number[] = []; meta.flattenEach(fcMixed, (feature, featureIndex, multiFeatureIndex) => { features.push(feature); featureIndexes.push(featureIndex); @@ -449,7 +467,10 @@ test("flattenReduce -- initialValue", (t) => { (previous, current, index, subIndex) => { lastIndex = index; lastSubIndex = subIndex; - return previous + current.geometry.coordinates[0]; + return ( + previous + + (current as unknown as Feature).geometry.coordinates[0] // Manual cast to Point required here because flattenReduce types don't correctly go from MultiFoo to Foo. + ); }, 0 ); @@ -461,8 +482,8 @@ test("flattenReduce -- initialValue", (t) => { test("flattenReduce -- previous-feature", (t) => { const features = []; - const featureIndexes = []; - const multiFeatureIndexes = []; + const featureIndexes: number[] = []; + const multiFeatureIndexes: number[] = []; meta.flattenReduce( multiLine, (previous, current, featureIndex, multiFeatureIndex) => { @@ -479,9 +500,9 @@ test("flattenReduce -- previous-feature", (t) => { }); test("flattenReduce -- previous-feature+initialValue", (t) => { - const features = []; - const featureIndexes = []; - const multiFeatureIndexes = []; + const features: Feature[] = []; + const featureIndexes: number[] = []; + const multiFeatureIndexes: number[] = []; const sum = meta.flattenReduce( multiPt.geometry, (previous, current, featureIndex, multiFeatureIndex) => { @@ -490,7 +511,7 @@ test("flattenReduce -- previous-feature+initialValue", (t) => { features.push(current); return current; }, - null + null as any ); t.deepEqual(featureIndexes, [0, 0]); t.deepEqual(multiFeatureIndexes, [0, 1]); @@ -505,7 +526,7 @@ test("null geometries", (t) => { meta.featureEach(fcNull, (feature) => t.equal(feature.geometry, null, "featureEach") ); - meta.geomEach(fcNull, (geometry) => t.equal(geometry, null), "geomEach"); + meta.geomEach(fcNull, (geometry) => t.equal(geometry, null, "geomEach")); meta.flattenEach(fcNull, (feature) => t.equal(feature.geometry, null, "flattenEach") ); @@ -550,7 +571,7 @@ test("null geometries -- index", (t) => { meta.coordReduce( fc, (prev, coords, coordIndex) => prev.concat(coordIndex), - [] + [] as number[] ), [0, 1, 2], "coordReduce" @@ -559,7 +580,7 @@ test("null geometries -- index", (t) => { meta.geomReduce( fc, (prev, geom, featureIndex) => prev.concat(featureIndex), - [] + [] as number[] ), [0, 1, 2, 3], "geomReduce" @@ -568,7 +589,7 @@ test("null geometries -- index", (t) => { meta.flattenReduce( fc, (prev, feature, featureIndex) => prev.concat(featureIndex), - [] + [] as number[] ), [0, 1, 2, 3], "flattenReduce" @@ -577,7 +598,7 @@ test("null geometries -- index", (t) => { }); test("segmentEach", (t) => { - const segments = []; + const segments: Feature[] = []; let total = 0; meta.segmentEach(poly.geometry, (currentSegment) => { segments.push(currentSegment); @@ -600,7 +621,7 @@ test("segmentEach -- MultiPoint", (t) => { }); test("segmentReduce", (t) => { - const segments = []; + const segments: Feature[] = []; const total = meta.segmentReduce( poly.geometry, (previousValue, currentSegment) => { @@ -616,7 +637,7 @@ test("segmentReduce", (t) => { }); test("segmentReduce -- no initialValue", (t) => { - const segments = []; + const segments: Feature[] = []; var total = 0; meta.segmentReduce(poly.geometry, (previousValue, currentSegment) => { segments.push(currentSegment); @@ -627,7 +648,9 @@ test("segmentReduce -- no initialValue", (t) => { t.end(); }); -const geojsonSegments = featureCollection([ +const geojsonSegments = featureCollection< + Point | LineString | Polygon | MultiLineString +>([ point([0, 1]), // ignored lineString([ [0, 0], @@ -659,10 +682,10 @@ const geojsonSegments = featureCollection([ ]); test("segmentEach -- index & subIndex", (t) => { - const featureIndexes = []; - const multiFeatureIndexes = []; - const geometryIndexes = []; - const segmentIndexes = []; + const featureIndexes: (number | undefined)[] = []; + const multiFeatureIndexes: (number | undefined)[] = []; + const geometryIndexes: (number | undefined)[] = []; + const segmentIndexes: (number | undefined)[] = []; let total = 0; meta.segmentEach( @@ -700,14 +723,14 @@ test("segmentEach -- index & subIndex", (t) => { }); test("segmentReduce -- index & subIndex", (t) => { - const featureIndexes = []; - const multiFeatureIndexes = []; - const geometryIndexes = []; - const segmentIndexes = []; + const featureIndexes: (number | undefined)[] = []; + const multiFeatureIndexes: (number | undefined)[] = []; + const geometryIndexes: (number | undefined)[] = []; + const segmentIndexes: (number | undefined)[] = []; let total = 0; meta.segmentReduce( - geojsonSegments, + geojsonSegments as FeatureCollection, // geojsonSegments contain Points, but they must be ignored at runtime ( previousValue, segment, @@ -753,9 +776,9 @@ test("lineEach -- lineString", (t) => { [2, 2], [4, 4], ]); - const featureIndexes = []; - const multiFeatureIndexes = []; - const lineIndexes = []; + const featureIndexes: (number | undefined)[] = []; + const multiFeatureIndexes: (number | undefined)[] = []; + const lineIndexes: (number | undefined)[] = []; let total = 0; meta.lineEach( @@ -787,9 +810,9 @@ test("lineEach -- multiLineString", (t) => { [5, 5], ], ]); - const featureIndexes = []; - const multiFeatureIndexes = []; - const lineIndexes = []; + const featureIndexes: (number | undefined)[] = []; + const multiFeatureIndexes: (number | undefined)[] = []; + const lineIndexes: (number | undefined)[] = []; let total = 0; meta.lineEach( @@ -834,9 +857,9 @@ test("lineEach -- multiPolygon", (t) => { ], // outer ], ]); - const featureIndexes = []; - const multiFeatureIndexes = []; - const lineIndexes = []; + const featureIndexes: (number | undefined)[] = []; + const multiFeatureIndexes: (number | undefined)[] = []; + const lineIndexes: (number | undefined)[] = []; let total = 0; meta.lineEach( @@ -898,13 +921,17 @@ test("lineEach -- featureCollection", (t) => { ], // outer ], ]); - const featureIndexes = []; - const multiFeatureIndexes = []; - const lineIndexes = []; + const featureIndexes: (number | undefined)[] = []; + const multiFeatureIndexes: (number | undefined)[] = []; + const lineIndexes: (number | undefined)[] = []; let total = 0; meta.lineEach( - featureCollection([line, multiLine, multiPoly]), + featureCollection([ + line, + multiLine, + multiPoly, + ]), (currentLine, featureIndex, multiFeatureIndex, lineIndex) => { featureIndexes.push(featureIndex); multiFeatureIndexes.push(multiFeatureIndex); @@ -936,10 +963,10 @@ test("lineReduce -- multiLineString", (t) => { const total = meta.lineReduce( multiLine, (previousValue) => { - previousValue++; - return previousValue; + previousValue!++; + return previousValue!; }, - 0 + 0 as number ); t.equal(total, 2, "total"); @@ -976,8 +1003,8 @@ test("lineReduce -- multiPolygon", (t) => { const total = meta.lineReduce( multiPoly, (previousValue) => { - previousValue++; - return previousValue; + previousValue!++; + return previousValue!; }, 0 ); @@ -995,10 +1022,10 @@ test("lineEach & lineReduce -- assert", (t) => { const noop = () => { /* no-op */ }; - meta.lineEach(pt, noop); // Point geometry is supported - meta.lineEach(multiPt, noop); // MultiPoint geometry is supported - meta.lineReduce(pt, noop); // Point geometry is supported - meta.lineReduce(multiPt, noop); // MultiPoint geometry is supported + meta.lineEach(pt as any, noop); // Point geometry is supported + meta.lineEach(multiPt as any, noop); // MultiPoint geometry is supported + meta.lineReduce(pt as any, noop); // Point geometry is supported + meta.lineReduce(multiPt as any, noop); // MultiPoint geometry is supported meta.lineReduce(geomCollection, noop); // GeometryCollection is is supported meta.lineReduce( featureCollection([ @@ -1009,13 +1036,13 @@ test("lineEach & lineReduce -- assert", (t) => { ]), noop ); // FeatureCollection is is supported - meta.lineReduce(feature(null), noop); // Feature with null geometry is supported + meta.lineReduce(feature(null) as any, noop); // Feature with null geometry is supported t.end(); }); test("geomEach -- callback BBox & Id", (t) => { const properties = { foo: "bar" }; - const bbox = [0, 0, 0, 0]; + const bbox: BBox = [0, 0, 0, 0]; const id = "foo"; const pt = point([0, 0], properties, { bbox, id }); @@ -1039,7 +1066,7 @@ test("geomEach -- callback BBox & Id", (t) => { test("lineEach -- callback BBox & Id", (t) => { const properties = { foo: "bar" }; - const bbox = [0, 0, 10, 10]; + const bbox: BBox = [0, 0, 10, 10]; const id = "foo"; const line = lineString( [ @@ -1061,7 +1088,7 @@ test("lineEach -- callback BBox & Id", (t) => { test("lineEach -- return lineString", (t) => { const properties = { foo: "bar" }; - const bbox = [0, 0, 10, 10]; + const bbox: BBox = [0, 0, 10, 10]; const id = "foo"; const line = lineString( [ @@ -1079,10 +1106,10 @@ test("lineEach -- return lineString", (t) => { }); test("meta.coordEach -- indexes -- PolygonWithHole", (t) => { - const coordIndexes = []; - const featureIndexes = []; - const multiFeatureIndexes = []; - const geometryIndexes = []; + const coordIndexes: number[] = []; + const featureIndexes: number[] = []; + const multiFeatureIndexes: number[] = []; + const geometryIndexes: number[] = []; meta.coordEach( polyWithHole, @@ -1101,9 +1128,9 @@ test("meta.coordEach -- indexes -- PolygonWithHole", (t) => { }); test("meta.lineEach -- indexes -- PolygonWithHole", (t) => { - const featureIndexes = []; - const multiFeatureIndexes = []; - const geometryIndexes = []; + const featureIndexes: (number | undefined)[] = []; + const multiFeatureIndexes: (number | undefined)[] = []; + const geometryIndexes: (number | undefined)[] = []; meta.lineEach( polyWithHole, @@ -1120,10 +1147,10 @@ test("meta.lineEach -- indexes -- PolygonWithHole", (t) => { }); test("meta.segmentEach -- indexes -- PolygonWithHole", (t) => { - const featureIndexes = []; - const multiFeatureIndexes = []; - const geometryIndexes = []; - const segmentIndexes = []; + const featureIndexes: (number | undefined)[] = []; + const multiFeatureIndexes: (number | undefined)[] = []; + const geometryIndexes: (number | undefined)[] = []; + const segmentIndexes: (number | undefined)[] = []; meta.segmentEach( polyWithHole, @@ -1143,10 +1170,10 @@ test("meta.segmentEach -- indexes -- PolygonWithHole", (t) => { }); test("meta.coordEach -- indexes -- Multi-Polygon with hole", (t) => { - const featureIndexes = []; - const multiFeatureIndexes = []; - const geometryIndexes = []; - const coordIndexes = []; + const featureIndexes: number[] = []; + const multiFeatureIndexes: number[] = []; + const geometryIndexes: number[] = []; + const coordIndexes: number[] = []; // MultiPolygon with hole // ====================== @@ -1221,10 +1248,10 @@ test("meta.coordEach -- indexes -- Multi-Polygon with hole", (t) => { }); test("meta.coordEach -- indexes -- Polygon with hole", (t) => { - const featureIndexes = []; - const multiFeatureIndexes = []; - const geometryIndexes = []; - const coordIndexes = []; + const featureIndexes: number[] = []; + const multiFeatureIndexes: number[] = []; + const geometryIndexes: number[] = []; + const coordIndexes: number[] = []; // Polygon with Hole // ================= @@ -1275,10 +1302,10 @@ test("meta.coordEach -- indexes -- Polygon with hole", (t) => { }); test("meta.coordEach -- indexes -- FeatureCollection of LineString", (t) => { - const featureIndexes = []; - const multiFeatureIndexes = []; - const geometryIndexes = []; - const coordIndexes = []; + const featureIndexes: number[] = []; + const multiFeatureIndexes: number[] = []; + const geometryIndexes: number[] = []; + const coordIndexes: number[] = []; // FeatureCollection of LineStrings const line = lineStrings([ @@ -1367,7 +1394,7 @@ test("meta -- breaking of iterations", (t) => { // FeatureCollection let count = 0; - func(lines, () => { + (func as any)(lines, () => { count += 1; return false; }); @@ -1375,7 +1402,7 @@ test("meta -- breaking of iterations", (t) => { // Multi Geometry let multiCount = 0; - func(multiLine, () => { + (func as any)(multiLine, () => { multiCount += 1; return false; }); @@ -1434,11 +1461,11 @@ test("meta -- findSegment", (t) => { ]); // firstSegment t.deepEqual( - meta.findSegment(nullFeature), + meta.findSegment(nullFeature as any), null, "findSegment (default) -- nullFeature" ); - t.deepEqual(meta.findSegment(pt), null, "findSegment (default) -- pt"); + t.deepEqual(meta.findSegment(pt as any), null, "findSegment (default) -- pt"); t.deepEqual( meta.findSegment(line), lineString([ @@ -1474,11 +1501,11 @@ test("meta -- findSegment", (t) => { // lastSegment t.deepEqual( - meta.findSegment(nullFeature), + meta.findSegment(nullFeature as any), null, "findSegment (last) -- nullFeature" ); - t.deepEqual(meta.findSegment(pt), null, "findSegment (last) -- pt"); + t.deepEqual(meta.findSegment(pt as any), null, "findSegment (last) -- pt"); t.deepEqual( meta.findSegment(line, { segmentIndex: -1 }), lineString([ @@ -1642,8 +1669,8 @@ test("meta -- segmentEach -- Issue #1273", (t) => { [-10, -10], ], ]); - const segmentIndexes = []; - const geometryIndexes = []; + const segmentIndexes: (number | undefined)[] = []; + const geometryIndexes: (number | undefined)[] = []; meta.segmentEach( poly, (line, featureIndex, multiFeatureIndex, segmentIndex, geometryIndex) => { diff --git a/packages/turf-meta/types.ts b/packages/turf-meta/types.ts index cd2e3a04ba..194ec3f65d 100644 --- a/packages/turf-meta/types.ts +++ b/packages/turf-meta/types.ts @@ -73,9 +73,15 @@ const customLineStrings = featureCollection([customLineString]); /** * meta.coordEach */ -const coordEachValue: void = meta.coordEach(pt, (coords) => coords); -coordEach(pt, (coords, index) => coords); -meta.coordEach(pt, (coords, index) => coords); +const coordEachValue = meta.coordEach(pt, (coords) => { + coords; +}); +coordEach(pt, (coords, index) => { + coords; +}); +meta.coordEach(pt, (coords, index) => { + coords; +}); meta.coordEach(pt.geometry, (coords) => { const equal: number[] = coords; }); @@ -88,7 +94,9 @@ meta.coordEach(poly, (coords) => { meta.coordEach(multiPoly, (coords) => { const equal: number[] = coords; }); -meta.coordEach(geomCollection, (coords) => coords); +meta.coordEach(geomCollection, (coords) => { + coords; +}); /** * meta.coordReduce @@ -120,12 +128,24 @@ meta.propReduce(geomCollection, (previous, prop) => prop); /** * meta.propEach */ -const propEachValue: void = meta.propEach(poly, (prop) => prop); -propEach(features, (prop) => prop); -meta.propEach(features, (prop) => prop); -meta.propEach(poly, (prop, index) => prop); -meta.propEach<{ bar: string }>(poly, (prop) => prop.bar); -meta.propEach(geomCollection, (prop) => prop); +const propEachValue: void = meta.propEach(poly, (prop) => { + prop; +}); +propEach(features, (prop) => { + prop; +}); +meta.propEach(features, (prop) => { + prop; +}); +meta.propEach(poly, (prop, index) => { + prop; +}); +meta.propEach<{ bar: string }>(poly, (prop) => { + prop.bar; +}); +meta.propEach(geomCollection, (prop) => { + prop; +}); /** * meta.coordAll @@ -149,11 +169,21 @@ meta.featureReduce(geomCollection, (previous, feature, index) => feature); /** * meta.featureEach */ -const featureEachValue: void = meta.featureEach(poly, (feature) => feature); -featureEach(features, (feature) => feature); -meta.featureEach(features, (feature) => feature); -meta.featureEach(poly, (feature, index) => feature); -meta.featureEach(geomCollection, (feature, index) => feature); +const featureEachValue: void = meta.featureEach(poly, (feature) => { + feature; +}); +featureEach(features, (feature) => { + feature; +}); +meta.featureEach(features, (feature) => { + feature; +}); +meta.featureEach(poly, (feature, index) => { + feature; +}); +meta.featureEach(geomCollection, (feature, index) => { + feature; +}); // Access custom properties featureEach(customPoints, (pt) => { @@ -177,11 +207,21 @@ meta.geomReduce(geomCollection, (previous, geom, index, props) => geom); /** * meta.geomEach */ -const geomEachValue: void = meta.geomEach(poly, (geom) => geom); -geomEach(features, (geom) => geom); -meta.geomEach(features, (geom) => geom); -meta.geomEach(poly, (geom, index, props) => geom); -meta.geomEach(geomCollection, (geom, index, props) => geom); +const geomEachValue = meta.geomEach(poly, (geom) => { + geom; +}); +geomEach(features, (geom) => { + geom; +}); +meta.geomEach(features, (geom) => { + geom; +}); +meta.geomEach(poly, (geom, index, props) => { + geom; +}); +meta.geomEach(geomCollection, (geom, index, props) => { + geom; +}); /** * meta.flattenReduce @@ -202,11 +242,21 @@ meta.flattenReduce( /** * meta.flattenEach */ -const flattenEachValue: void = meta.flattenEach(poly, (feature) => feature); -flattenEach(features, (feature) => feature); -meta.flattenEach(features, (feature) => feature); -meta.flattenEach(poly.geometry, (feature, index, props) => feature); -meta.flattenEach(geomCollection, (feature, index, props) => feature); +const flattenEachValue: void = meta.flattenEach(poly, (feature) => { + feature; +}); +flattenEach(features, (feature) => { + feature; +}); +meta.flattenEach(features, (feature) => { + feature; +}); +meta.flattenEach(poly.geometry, (feature, index, props) => { + feature; +}); +meta.flattenEach(geomCollection, (feature, index, props) => { + feature; +}); /** * meta.segmentReduce @@ -238,20 +288,26 @@ meta.segmentReduce( const segmentEachValue: void = meta.segmentEach(poly, () => { /* no-op */ }); -segmentEach(poly, (currentSegment) => currentSegment); -meta.segmentEach(poly, (currentSegment) => currentSegment); -meta.segmentEach(features, (currentSegment) => currentSegment); -meta.segmentEach( - poly.geometry, - (currentSegment, currentIndex) => currentSegment -); -meta.segmentEach( - geomCollection, - (currentSegment, currentIndex) => currentSegment -); +segmentEach(poly, (currentSegment) => { + currentSegment; +}); +meta.segmentEach(poly, (currentSegment) => { + currentSegment; +}); +meta.segmentEach(features, (currentSegment) => { + currentSegment; +}); +meta.segmentEach(poly.geometry, (currentSegment, currentIndex) => { + currentSegment; +}); +meta.segmentEach(geomCollection, (currentSegment, currentIndex) => { + currentSegment; +}); meta.segmentEach( geomCollection, - (currentSegment, currentIndex, currentSubIndex) => currentSegment + (currentSegment, currentIndex, currentSubIndex) => { + currentSegment; + } ); /** @@ -261,20 +317,26 @@ meta.segmentEach( const lineEachValue: void = meta.lineEach(line, () => { /* no-op */ }); -lineEach(line, (currentLine) => currentLine); -meta.lineEach(line, (currentLine) => currentLine); -meta.lineEach( - multiLine, - (currentLine, featureIndex, featureSubIndex) => currentLine -); -meta.lineEach(poly, (currentLine) => currentLine); -meta.lineEach( - poly, - (currentLine, featureIndex, featureSubIndex, lineIndex) => currentLine -); +lineEach(line, (currentLine) => { + currentLine; +}); +meta.lineEach(line, (currentLine) => { + currentLine; +}); +meta.lineEach(multiLine, (currentLine, featureIndex, featureSubIndex) => { + currentLine; +}); +meta.lineEach(poly, (currentLine) => { + currentLine; +}); +meta.lineEach(poly, (currentLine, featureIndex, featureSubIndex, lineIndex) => { + currentLine; +}); meta.lineEach( multiPoly, - (currentLine, featureIndex, featureSubIndex, lineIndex) => currentLine + (currentLine, featureIndex, featureSubIndex, lineIndex) => { + currentLine; + } ); // Able to load custom LineStrings diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5c55bab49f..16a0920ab9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4121,6 +4121,9 @@ importers: '@types/geojson': specifier: ^7946.0.10 version: 7946.0.14 + tslib: + specifier: ^2.8.1 + version: 2.8.1 devDependencies: '@turf/random': specifier: workspace:* @@ -4128,6 +4131,9 @@ importers: '@types/benchmark': specifier: ^2.1.5 version: 2.1.5 + '@types/tape': + specifier: ^5.8.1 + version: 5.8.1 benchmark: specifier: ^2.1.4 version: 2.1.4 @@ -4140,6 +4146,9 @@ importers: tsx: specifier: ^4.19.4 version: 4.19.4 + typescript: + specifier: ^5.8.3 + version: 5.8.3 packages/turf-midpoint: dependencies: