flauwekeul / honeycomb

Create hex grids easily, in node or the browser.
https://abbekeultjes.nl/honeycomb
MIT License
630 stars 57 forks source link

Some recommended patterns for working with hex prototypes don't work in typescript #64

Closed rcoppy closed 3 years ago

rcoppy commented 3 years ago

Hi! This is maybe beyond the scope of this library, but I'm trying to use it in a node application written in typescript.

For my implementation I need to be able to override the default hex prototype so that it includes a Hex's unique index in addition to its cartesian coordinates.

Example code for doing something similar is provided in the docs:

You can define a toJSON() method on your Hex prototype to control how a grid is serialized:


const hexPrototype = {
toJSON() { return [this.x, this.y] }
}
const Hex = Honeycomb.extendHex(hexPrototype)
const Grid = Honeycomb.defineGrid(Hex)
const grid = Grid.rectangle({ width: 2, height: 2 })

const serializedGrid = JSON.stringify(grid) // [[0,0],[1,0],[0,1],[1,1]]


Unfortunately typescript (by design, in order to enforce type safety) doesn't permit:  `toJSON() { return [this.x, this.y] }`

Because it's ambiguous whether or not the target of `this` actually possesses `x` or `y` as properties.

Ideally I'd like to just be able to write:
`return [this.x, this.y, grid.indexOf([0,0])`

Although because of scoping I can also see that not working, either.

Thank you!!
flauwekeul commented 3 years ago

Have you tried assigning a type to this in toJSON()?

import { extendHex, defineGrid, Hex } from "https://cdn.skypack.dev/honeycomb-grid@3.1.7";

interface CustomHex {
  toJSON(): [number, number]
  index: number
}

const hexPrototype: CustomHex = {
  toJSON(this: Hex<CustomHex>) { return [this.x, this.y, this.index] }
      // ^^^ you can give `this` a type like so
}
const Hex = extendHex(hexPrototype)
const Grid = defineGrid(Hex)
const grid = Grid.rectangle({ width: 2, height: 2 }).map((hex, i) => {
  hex.index = i
  return hex
})

console.log(JSON.stringify(grid))

You can play around with this on codepen if you like. TypeScripts Handbook offers more information.

rcoppy commented 3 years ago

Wow!! Thank you so much for taking the time to write such a thorough example 😄🙏 I'm fairly new to typescript, so this is extremely helpful. All the best!