Skip to content

Commit ece84ef

Browse files
authored
Merge pull request #153 from nrabinowitz/typescript-libdef
Add Typescript typechecking, generate types with tsc
2 parents 7eeeb99 + 2593335 commit ece84ef

11 files changed

+213
-109
lines changed

README.md

+44-27
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@ const coordinates = h3.cellsToMultiPolygon(hexagons, true);
9898
## h3
9999

100100
* [h3](#module_h3)
101-
* [.UNITS](#module_h3.UNITS) : <code>Object</code>
102-
* [.h3IndexToSplitLong(h3Index)](#module_h3.h3IndexToSplitLong) ⇒ <code>Array.&lt;number&gt;</code>
101+
* [.UNITS](#module_h3.UNITS)
102+
* [.h3IndexToSplitLong(h3Index)](#module_h3.h3IndexToSplitLong) ⇒ <code>SplitLong</code>
103103
* [.splitLongToH3Index(lower, upper)](#module_h3.splitLongToH3Index) ⇒ <code>H3Index</code>
104104
* [.isValidCell(h3Index)](#module_h3.isValidCell) ⇒ <code>boolean</code>
105105
* [.isPentagon(h3Index)](#module_h3.isPentagon) ⇒ <code>boolean</code>
@@ -108,16 +108,16 @@ const coordinates = h3.cellsToMultiPolygon(hexagons, true);
108108
* [.getIcosahedronFaces(h3Index)](#module_h3.getIcosahedronFaces) ⇒ <code>Array.&lt;number&gt;</code>
109109
* [.getResolution(h3Index)](#module_h3.getResolution) ⇒ <code>number</code>
110110
* [.latLngToCell(lat, lng, res)](#module_h3.latLngToCell) ⇒ <code>H3Index</code>
111-
* [.cellToLatLng(h3Index)](#module_h3.cellToLatLng) ⇒ <code>Array.&lt;number&gt;</code>
112-
* [.cellToBoundary(h3Index, [formatAsGeoJson])](#module_h3.cellToBoundary) ⇒ <code>Array.&lt;Array.&lt;number&gt;&gt;</code>
111+
* [.cellToLatLng(h3Index)](#module_h3.cellToLatLng) ⇒ <code>CoordPair</code>
112+
* [.cellToBoundary(h3Index, [formatAsGeoJson])](#module_h3.cellToBoundary) ⇒ <code>Array.&lt;CoordPair&gt;</code>
113113
* [.cellToParent(h3Index, res)](#module_h3.cellToParent) ⇒ <code>H3Index</code>
114114
* [.cellToChildren(h3Index, res)](#module_h3.cellToChildren) ⇒ <code>Array.&lt;H3Index&gt;</code>
115115
* [.cellToCenterChild(h3Index, res)](#module_h3.cellToCenterChild) ⇒ <code>H3Index</code>
116116
* [.gridDisk(h3Index, ringSize)](#module_h3.gridDisk) ⇒ <code>Array.&lt;H3Index&gt;</code>
117117
* [.gridDiskDistances(h3Index, ringSize)](#module_h3.gridDiskDistances) ⇒ <code>Array.&lt;Array.&lt;H3Index&gt;&gt;</code>
118118
* [.gridRingUnsafe(h3Index, ringSize)](#module_h3.gridRingUnsafe) ⇒ <code>Array.&lt;H3Index&gt;</code>
119119
* [.polygonToCells(coordinates, res, [isGeoJson])](#module_h3.polygonToCells) ⇒ <code>Array.&lt;H3Index&gt;</code>
120-
* [.cellsToMultiPolygon(h3Indexes, [formatAsGeoJson])](#module_h3.cellsToMultiPolygon) ⇒ <code>Array.&lt;Array.&lt;Array.&lt;Array.&lt;number&gt;&gt;&gt;&gt;</code>
120+
* [.cellsToMultiPolygon(h3Indexes, [formatAsGeoJson])](#module_h3.cellsToMultiPolygon) ⇒ <code>Array.&lt;Array.&lt;Array.&lt;CoordPair&gt;&gt;&gt;</code>
121121
* [.compactCells(h3Set)](#module_h3.compactCells) ⇒ <code>Array.&lt;H3Index&gt;</code>
122122
* [.uncompactCells(compactedSet, res)](#module_h3.uncompactCells) ⇒ <code>Array.&lt;H3Index&gt;</code>
123123
* [.areNeighborCells(origin, destination)](#module_h3.areNeighborCells) ⇒ <code>boolean</code>
@@ -127,7 +127,7 @@ const coordinates = h3.cellsToMultiPolygon(hexagons, true);
127127
* [.isValidDirectedEdge(edgeIndex)](#module_h3.isValidDirectedEdge) ⇒ <code>boolean</code>
128128
* [.directedEdgeToCells(edgeIndex)](#module_h3.directedEdgeToCells) ⇒ <code>Array.&lt;H3Index&gt;</code>
129129
* [.originToDirectedEdges(h3Index)](#module_h3.originToDirectedEdges) ⇒ <code>Array.&lt;H3Index&gt;</code>
130-
* [.directedEdgeToBoundary(edgeIndex, [formatAsGeoJson])](#module_h3.directedEdgeToBoundary) ⇒ <code>Array.&lt;Array.&lt;number&gt;&gt;</code>
130+
* [.directedEdgeToBoundary(edgeIndex, [formatAsGeoJson])](#module_h3.directedEdgeToBoundary) ⇒ <code>Array.&lt;CoordPair&gt;</code>
131131
* [.gridDistance(origin, destination)](#module_h3.gridDistance) ⇒ <code>number</code>
132132
* [.gridPathCells(origin, destination)](#module_h3.gridPathCells) ⇒ <code>Array.&lt;H3Index&gt;</code>
133133
* [.cellToLocalIj(origin, destination)](#module_h3.cellToLocalIj) ⇒ <code>CoordIJ</code>
@@ -139,7 +139,7 @@ const coordinates = h3.cellsToMultiPolygon(hexagons, true);
139139
* [.getHexagonEdgeLengthAvg(res, unit)](#module_h3.getHexagonEdgeLengthAvg) ⇒ <code>number</code>
140140
* [.cellToVertex(h3Index, vertexNum)](#module_h3.cellToVertex) ⇒ <code>H3Index</code>
141141
* [.cellToVertexes(h3Index)](#module_h3.cellToVertexes) ⇒ <code>Array.&lt;H3Index&gt;</code>
142-
* [.vertexToLatLng(h3Index)](#module_h3.vertexToLatLng) ⇒ <code>Array.&lt;number&gt;</code>
142+
* [.vertexToLatLng(h3Index)](#module_h3.vertexToLatLng) ⇒ <code>CoordPair</code>
143143
* [.isValidVertex(h3Index)](#module_h3.isValidVertex) ⇒ <code>boolean</code>
144144
* [.getNumCells(res)](#module_h3.getNumCells) ⇒ <code>number</code>
145145
* [.getRes0Cells()](#module_h3.getRes0Cells) ⇒ <code>Array.&lt;H3Index&gt;</code>
@@ -148,15 +148,17 @@ const coordinates = h3.cellsToMultiPolygon(hexagons, true);
148148
* [.radsToDegs(rad)](#module_h3.radsToDegs) ⇒ <code>number</code>
149149
* [.H3Index](#module_h3.H3Index) : <code>string</code>
150150
* [.H3IndexInput](#module_h3.H3IndexInput) : <code>string</code> \| <code>Array.&lt;number&gt;</code>
151-
* [.CoordIJ](#module_h3.CoordIJ) : <code>Object</code>
152-
* [.H3Error](#module_h3.H3Error) ⇐ <code>Error</code>
151+
* [.CoordIJ](#module_h3.CoordIJ)
152+
* [.H3Error](#module_h3.H3Error)
153+
* [.CoordPair](#module_h3.CoordPair) : <code>Array.&lt;number&gt;</code>
154+
* [.SplitLong](#module_h3.SplitLong) : <code>Array.&lt;number&gt;</code>
153155

154156

155157
* * *
156158

157159
<a name="module_h3.UNITS"></a>
158160

159-
### h3.UNITS : <code>Object</code>
161+
### h3.UNITS
160162
Length/Area units
161163

162164
**Properties**
@@ -175,10 +177,10 @@ Length/Area units
175177

176178
<a name="module_h3.h3IndexToSplitLong"></a>
177179

178-
### h3.h3IndexToSplitLong(h3Index) ⇒ <code>Array.&lt;number&gt;</code>
180+
### h3.h3IndexToSplitLong(h3Index) ⇒ <code>SplitLong</code>
179181
Convert an H3 index (64-bit hexidecimal string) into a "split long" - a pair of 32-bit ints
180182

181-
**Returns**: <code>Array.&lt;number&gt;</code> - A two-element array with 32 lower bits and 32 upper bits
183+
**Returns**: <code>SplitLong</code> - A two-element array with 32 lower bits and 32 upper bits
182184

183185
| Param | Type | Description |
184186
| --- | --- | --- |
@@ -314,10 +316,10 @@ Get the hexagon containing a lat,lon point
314316

315317
<a name="module_h3.cellToLatLng"></a>
316318

317-
### h3.cellToLatLng(h3Index) ⇒ <code>Array.&lt;number&gt;</code>
319+
### h3.cellToLatLng(h3Index) ⇒ <code>CoordPair</code>
318320
Get the lat,lon center of a given hexagon
319321

320-
**Returns**: <code>Array.&lt;number&gt;</code> - Point as a [lat, lng] pair
322+
**Returns**: <code>CoordPair</code> - Point as a [lat, lng] pair
321323
**Throws**:
322324

323325
- <code>H3Error</code> If input is invalid
@@ -332,12 +334,12 @@ Get the lat,lon center of a given hexagon
332334

333335
<a name="module_h3.cellToBoundary"></a>
334336

335-
### h3.cellToBoundary(h3Index, [formatAsGeoJson]) ⇒ <code>Array.&lt;Array.&lt;number&gt;&gt;</code>
337+
### h3.cellToBoundary(h3Index, [formatAsGeoJson]) ⇒ <code>Array.&lt;CoordPair&gt;</code>
336338
Get the vertices of a given hexagon (or pentagon), as an array of [lat, lng]
337339
points. For pentagons and hexagons on the edge of an icosahedron face, this
338340
function may return up to 10 vertices.
339341

340-
**Returns**: <code>Array.&lt;Array.&lt;number&gt;&gt;</code> - Array of [lat, lng] pairs
342+
**Returns**: <code>Array.&lt;CoordPair&gt;</code> - Array of [lat, lng] pairs
341343
**Throws**:
342344

343345
- <code>H3Error</code> If input is invalid
@@ -494,7 +496,7 @@ expected to be holes.
494496

495497
<a name="module_h3.cellsToMultiPolygon"></a>
496498

497-
### h3.cellsToMultiPolygon(h3Indexes, [formatAsGeoJson]) ⇒ <code>Array.&lt;Array.&lt;Array.&lt;Array.&lt;number&gt;&gt;&gt;&gt;</code>
499+
### h3.cellsToMultiPolygon(h3Indexes, [formatAsGeoJson]) ⇒ <code>Array.&lt;Array.&lt;Array.&lt;CoordPair&gt;&gt;&gt;</code>
498500
Get the outlines of a set of H3 hexagons, returned in GeoJSON MultiPolygon
499501
format (an array of polygons, each with an array of loops, each an array of
500502
coordinates). Coordinates are returned as [lat, lng] pairs unless GeoJSON
@@ -505,7 +507,7 @@ set have the same resolution and that the set contains no duplicates. Behavior
505507
is undefined if duplicates or multiple resolutions are present, and the
506508
algorithm may produce unexpected or invalid polygons.
507509

508-
**Returns**: <code>Array.&lt;Array.&lt;Array.&lt;Array.&lt;number&gt;&gt;&gt;&gt;</code> - MultiPolygon-style output.
510+
**Returns**: <code>Array.&lt;Array.&lt;Array.&lt;CoordPair&gt;&gt;&gt;</code> - MultiPolygon-style output.
509511
**Throws**:
510512

511513
- <code>H3Error</code> If input is invalid
@@ -514,7 +516,7 @@ algorithm may produce unexpected or invalid polygons.
514516
| Param | Type | Description |
515517
| --- | --- | --- |
516518
| h3Indexes | <code>Array.&lt;H3IndexInput&gt;</code> | H3 indexes to get outlines for |
517-
| [formatAsGeoJson] | <code>boolean</code> | Whether to provide GeoJSON output: [lng, lat], closed loops |
519+
| [formatAsGeoJson] | <code>boolean</code> | Whether to provide GeoJSON output: [lng, lat], closed loops |
518520

519521

520522
* * *
@@ -684,11 +686,11 @@ every neighbor)
684686

685687
<a name="module_h3.directedEdgeToBoundary"></a>
686688

687-
### h3.directedEdgeToBoundary(edgeIndex, [formatAsGeoJson]) ⇒ <code>Array.&lt;Array.&lt;number&gt;&gt;</code>
689+
### h3.directedEdgeToBoundary(edgeIndex, [formatAsGeoJson]) ⇒ <code>Array.&lt;CoordPair&gt;</code>
688690
Get the vertices of a given edge as an array of [lat, lng] points. Note that for edges that
689691
cross the edge of an icosahedron face, this may return 3 coordinates.
690692

691-
**Returns**: <code>Array.&lt;Array.&lt;number&gt;&gt;</code> - Array of geo coordinate pairs
693+
**Returns**: <code>Array.&lt;CoordPair&gt;</code> - Array of geo coordinate pairs
692694
**Throws**:
693695

694696
- <code>H3Error</code> If the input is invalid
@@ -947,10 +949,10 @@ Find the indexes for all vertexes of a cell.
947949

948950
<a name="module_h3.vertexToLatLng"></a>
949951

950-
### h3.vertexToLatLng(h3Index) ⇒ <code>Array.&lt;number&gt;</code>
952+
### h3.vertexToLatLng(h3Index) ⇒ <code>CoordPair</code>
951953
Get the lat, lng of a given vertex
952954

953-
**Returns**: <code>Array.&lt;number&gt;</code> - Latitude, longitude coordinates of the vertex
955+
**Returns**: <code>CoordPair</code> - Latitude, longitude coordinates of the vertex
954956
**Throws**:
955957

956958
- <code>H3Error</code> If the input is invalid
@@ -1073,7 +1075,7 @@ or two 32-bit integers in little endian order in an array.
10731075

10741076
<a name="module_h3.CoordIJ"></a>
10751077

1076-
### h3.CoordIJ : <code>Object</code>
1078+
### h3.CoordIJ
10771079
Coordinates as an `{i, j}` pair
10781080

10791081
**Properties**
@@ -1088,11 +1090,10 @@ Coordinates as an `{i, j}` pair
10881090

10891091
<a name="module_h3.H3Error"></a>
10901092

1091-
### h3.H3Error ⇐ <code>Error</code>
1092-
Custom JS Error with an attached error code. Error codes come from the
1093+
### h3.H3Error
1094+
Custom JS Error instance with an attached error code. Error codes come from the
10931095
core H3 library and can be found [in the H3 docs](https://h3geo.org/docs/next/library/errors#table-of-error-codes).
10941096

1095-
**Extends**: <code>Error</code>
10961097
**Properties**
10971098

10981099
| Name | Type |
@@ -1101,6 +1102,22 @@ core H3 library and can be found [in the H3 docs](https://h3geo.org/docs/next/li
11011102
| code | <code>number</code> |
11021103

11031104

1105+
* * *
1106+
1107+
<a name="module_h3.CoordPair"></a>
1108+
1109+
### h3.CoordPair : <code>Array.&lt;number&gt;</code>
1110+
Pair of lat,lng coordinates (or lng,lat if GeoJSON output is specified)
1111+
1112+
1113+
* * *
1114+
1115+
<a name="module_h3.SplitLong"></a>
1116+
1117+
### h3.SplitLong : <code>Array.&lt;number&gt;</code>
1118+
Pair of lower,upper 32-bit ints representing a 64-bit value
1119+
1120+
11041121
* * *
11051122

11061123

build/pre.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// @ts-nocheck

lib/bindings.js

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ const POINTER = NUMBER;
2828
// Define the bindings to functions in the C lib. Functions are defined as
2929
// [name, return type, [arg types]]. You must run `npm run build-emscripten`
3030
// before new functions added here will be available.
31+
/** @type {([string, string] | [string, string | null, string[]])[]} */
3132
export default [
3233
// The size functions are inserted via build/sizes.h
3334
['sizeOfH3Index', NUMBER],

lib/errors.js

+9-6
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ const H3_ERROR_MSGS = {
5959
// Error codes for JS errors thrown in the bindings
6060
export const E_UNKNOWN_UNIT = 1000;
6161
export const E_ARRAY_LENGTH = 1001;
62+
export const E_NULL_INDEX = 1002;
6263

6364
/**
6465
* Error messages for errors thrown in the binding code. These don't strictly
@@ -67,7 +68,8 @@ export const E_ARRAY_LENGTH = 1001;
6768
*/
6869
const JS_ERROR_MESSAGES = {
6970
[E_UNKNOWN_UNIT]: 'Unknown unit',
70-
[E_ARRAY_LENGTH]: 'Array length out of bounds'
71+
[E_ARRAY_LENGTH]: 'Array length out of bounds',
72+
[E_NULL_INDEX]: 'Got unexpected null value for H3 index'
7173
};
7274

7375
const UNKNOWN_ERROR_MSG = 'Unknown error';
@@ -77,17 +79,18 @@ const UNKNOWN_ERROR_MSG = 'Unknown error';
7779
* @private
7880
* @param {Record<number, string>} messages Map of code-to-messages to use
7981
* @param {number} errCode Numeric error code
80-
* @param {{value: unknown}} meta Metadata with value to associate with the error
82+
* @param {{value: unknown} | {}} [meta] Metadata with value to associate with the error
8183
*/
8284
function createError(messages, errCode, meta) {
8385
// The error value may be "undefined", so check if the argument was provided
84-
const hasValue = 'value' in meta;
86+
const hasValue = meta && 'value' in meta;
8587
// Throw a custom error type with the code attached
8688
const err = new Error(
8789
`${messages[errCode] || UNKNOWN_ERROR_MSG} (code: ${errCode}${
8890
hasValue ? `, value: ${meta.value}` : ''
8991
})`
9092
);
93+
// @ts-expect-error - TS doesn't like extending Error
9194
err.code = errCode;
9295
return err;
9396
}
@@ -96,7 +99,7 @@ function createError(messages, errCode, meta) {
9699
* Custom error for H3Error codes
97100
* @private
98101
* @param {number} errCode Error code from the H3 library
99-
* @param {unknown} value Value to associate with the error, if any
102+
* @param {unknown} [value] Value to associate with the error, if any
100103
* @returns {Error}
101104
*/
102105
export function H3LibraryError(errCode, value) {
@@ -109,7 +112,7 @@ export function H3LibraryError(errCode, value) {
109112
* Custom errors thrown from the JS bindings.
110113
* @private
111114
* @param {number} errCode Error code from the H3 library
112-
* @param {unknown} value Value to associate with the error, if any
115+
* @param {unknown} [value] Value to associate with the error, if any
113116
* @returns {Error}
114117
*/
115118
export function JSBindingError(errCode, value) {
@@ -121,7 +124,7 @@ export function JSBindingError(errCode, value) {
121124
/**
122125
* Throw a JavaScript error if the C library return code is an error
123126
* @private
124-
* @param {number} err Error code from the H3 library
127+
* @param {number} errCode Error code from the H3 library
125128
* @throws {Error} Error if err is not E_SUCCESS (0)
126129
*/
127130
export function throwIfError(errCode) {

0 commit comments

Comments
 (0)