Repository: League-of-Foundry-Developers/foundry-vtt-types
Pull request #3172 (2025-02-16 00:07:38)

Types and tests for `client/pixi/layers/grid/**`


Patch:
diff --git a/src/foundry/client/config.d.mts b/src/foundry/client/config.d.mts
index be88ec712..68b69536a 100644
--- a/src/foundry/client/config.d.mts
+++ b/src/foundry/client/config.d.mts
@@ -1021,7 +1021,93 @@ declare global {
       /** @defaultValue `4` */
       objectBorderThickness: number;
 
-      gridStyles: Record<string, CONFIG.Canvas.GridStyle>;
+      gridStyles: {
+        [key: string]: GridLayer.GridStyle;
+
+        /**
+         * @defaultValue
+         * ```js
+         * {
+         *   label: "GRID.STYLES.SolidLines",
+         *   shaderClass: GridShader,
+         *   shaderOptions: {
+         *     style: 0
+         *   }
+         * }
+         * ```
+         */
+        solidLines: GridLayer.GridStyle;
+
+        /**
+         * @defaultValue
+         * ```js
+         * {
+         *   label: "GRID.STYLES.DashedLines",
+         *   shaderClass: GridShader,
+         *   shaderOptions: {
+         *     style: 1
+         *   }
+         * }
+         * ```
+         */
+        dashedLines: GridLayer.GridStyle;
+
+        /**
+         * @defaultValue
+         * ```js
+         * {
+         *   label: "GRID.STYLES.DottedLines",
+         *   shaderClass: GridShader,
+         *   shaderOptions: {
+         *     style: 0
+         *   }
+         * }
+         * ```
+         */
+        dottedLines: GridLayer.GridStyle;
+
+        /**
+         * @defaultValue
+         * ```js
+         * {
+         *   label: "GRID.STYLES.SquarePoints",
+         *   shaderClass: GridShader,
+         *   shaderOptions: {
+         *     style: 0
+         *   }
+         * }
+         * ```
+         */
+        squarePoints: GridLayer.GridStyle;
+
+        /**
+         * @defaultValue
+         * ```js
+         * {
+         *   label: "GRID.STYLES.DiamondPoints",
+         *   shaderClass: GridShader,
+         *   shaderOptions: {
+         *     style: 0
+         *   }
+         * }
+         * ```
+         */
+        diamondPoints: GridLayer.GridStyle;
+
+        /**
+         * @defaultValue
+         * ```js
+         * {
+         *   label: "GRID.STYLES.RoundPoints",
+         *   shaderClass: GridShader,
+         *   shaderOptions: {
+         *     style: 0
+         *   }
+         * }
+         * ```
+         */
+        roundPoints: GridLayer.GridStyle;
+      };
 
       lightAnimations: CONFIG.Canvas.LightSourceAnimationConfig & {
         flame: {
diff --git a/src/foundry/client/pixi/layers/grid/highlight.d.mts b/src/foundry/client/pixi/layers/grid/highlight.d.mts
index da917f1bf..c39cd437a 100644
--- a/src/foundry/client/pixi/layers/grid/highlight.d.mts
+++ b/src/foundry/client/pixi/layers/grid/highlight.d.mts
@@ -15,7 +15,7 @@ declare global {
     /**
      * Track distinct positions which have already been highlighted
      */
-    positions: Set<string>;
+    positions: Set<GridHighlight.PositionString>;
 
     /**
      * Record a position that is highlighted and return whether or not it should be rendered
@@ -27,7 +27,17 @@ declare global {
 
     override clear(): this;
 
-    /** @privateRemarks Foundry handles this by passing `(...args)` directly to super, but it only takes the one */
     override destroy(options?: PIXI.IDestroyOptions | boolean): void;
   }
+
+  namespace GridHighlight {
+    interface Any extends AnyGridHightlight {}
+    type AnyConstructor = typeof AnyGridHightlight;
+
+    type PositionString = `${number},${number}`;
+  }
+}
+
+declare abstract class AnyGridHightlight extends GridHighlight {
+  constructor(arg0: never, ...args: never[]);
 }
diff --git a/src/foundry/client/pixi/layers/grid/layer.d.mts b/src/foundry/client/pixi/layers/grid/layer.d.mts
index 51284a4bf..be69ba037 100644
--- a/src/foundry/client/pixi/layers/grid/layer.d.mts
+++ b/src/foundry/client/pixi/layers/grid/layer.d.mts
@@ -1,4 +1,4 @@
-import type { HandleEmptyObject, InexactPartial, NullishProps } from "fvtt-types/utils";
+import type { EmptyObject, HandleEmptyObject, NullishProps, RemoveIndexSignatures } from "fvtt-types/utils";
 
 declare global {
   /**
@@ -15,12 +15,14 @@ declare global {
     /**
      * The grid mesh.
      * @defaultValue `undefined`
+     * @remarks Only `undefined` prior to first draw
      */
     mesh: GridMesh | undefined;
 
     /**
      * The Grid Highlight container
      * @defaultValue `undefined`
+     * @remarks Only `undefined` prior to first draw
      */
     highlight: PIXI.Container | undefined;
 
@@ -40,38 +42,18 @@ declare global {
 
     override options: GridLayer.LayerOptions;
 
-    /**
-     * Draw the grid
-     * @param options - Override settings used in place of those saved to the Scene data
-     */
-    _draw(options: HandleEmptyObject<GridLayer.DrawOptions>): Promise<void>;
+    protected override _draw(options: HandleEmptyObject<GridLayer.DrawOptions>): Promise<void>;
 
     /**
      * Creates the grid mesh.
      */
-    protected _drawMesh(): Promise<ReturnType<GridMesh["initialize"]>>;
+    protected _drawMesh(): GridMesh;
 
     /**
      * Initialize the grid mesh appearance and configure the grid shader.
+     * @remarks All the properties of `options` are optional, but it lacks an `={}` default so an object must be passed, even if empty
      */
-    initializeMesh(
-      /**
-       * @remarks Can't be NullishProps because ultimately `GridMesh#_initialize` does `!== undefined` checks
-       */
-      options?: InexactPartial<{
-        /** The grid style */
-        style: string; //TODO: Update as part of #2572 to keyof CONFIG["Canvas"]["gridStyles"];
-
-        /** The grid thickness */
-        thickness: number;
-
-        /** The grid color */
-        color: string;
-
-        /** The grid alpha */
-        alpha: number;
-      }>,
-    ): void;
+    initializeMesh(options: GridLayer.InitializeMeshOptions): void;
 
     /**
      * Define a new Highlight graphic
@@ -101,98 +83,95 @@ declare global {
      * Add highlighting for a specific grid position to a named highlight graphic
      * @param name    - The name for the referenced highlight layer
      * @param options - Options for the grid position that should be highlighted
+     * @remarks Despite being an `={}` parameter, `options` is required, as not providing `x` or `y` produces `NaN`s
+     * or puts garbage data into the associated `GridHightlightLayer`, depending on the current grid type
      */
     highlightPosition(name: string, options: GridLayer.HighlightPositionOptions): void;
 
     /**
      * @deprecated since v12, will be removed in v14
-     * @remarks `"GridLayer#type is deprecated. Use canvas.grid.type instead."`
+     * @remarks "GridLayer#type is deprecated. Use canvas.grid.type instead."
      */
     get type(): foundry.CONST.GRID_TYPES;
 
     /**
      * @deprecated since v12, will be removed in v14
-     * @remarks `"GridLayer#size is deprecated. Use canvas.grid.size instead.`
+     * @remarks "GridLayer#size is deprecated. Use canvas.grid.size instead.
      */
     get size(): number;
 
     /**
      * @deprecated since v12, will be removed in v14
-     * `"GridLayer#grid is deprecated. Use canvas.grid instead."`
+     * @remarks "GridLayer#grid is deprecated. Use canvas.grid instead."
      */
-    grid: Canvas["grid"];
+    get grid(): Canvas["grid"];
 
     /**
      * @deprecated since v12, will be removed in v14
-     * @remarks `"GridLayer#isNeighbor is deprecated. Use canvas.grid.testAdjacency instead."`
+     * @remarks "GridLayer#isNeighbor is deprecated. Use canvas.grid.testAdjacency instead."
      */
     isNeighbor(r0: number, c0: number, r1: number, c1: number): boolean;
 
     /**
      * @deprecated since v12, will be removed in v14
-     * @remarks `"GridLayer#w is deprecated in favor of canvas.grid.sizeX."`
+     * @remarks "GridLayer#w is deprecated in favor of canvas.grid.sizeX."
      */
     get w(): number;
 
     /**
      * @deprecated since v12, will be removed in v14
-     * @remarks `"GridLayer#h is deprecated in favor of canvas.grid.sizeY."`
+     * @remarks "GridLayer#h is deprecated in favor of canvas.grid.sizeY."
      */
     get h(): number;
 
     /**
      * @deprecated since v12, will be removed in v14
-     * @remarks `"GridLayer#isHex is deprecated. Use canvas.grid.isHexagonal instead."`
+     * @remarks "GridLayer#isHex is deprecated. Use canvas.grid.isHexagonal instead."
      */
     get isHex(): boolean;
 
     /**
      * @deprecated since v12, will be removed in v14
-     * @remarks `"GridLayer#getTopLeft is deprecated. Use canvas.grid.getTopLeftPoint instead."`
+     * @remarks "GridLayer#getTopLeft is deprecated. Use canvas.grid.getTopLeftPoint instead."
      */
     getTopLeft(x: number, y: number): Canvas.PointTuple;
 
     /**
      * @deprecated since v12, will be removed in v14
-     * @remarks `"GridLayer#getCenter is deprecated. Use canvas.grid.getCenterPoint instead."`
+     * @remarks "GridLayer#getCenter is deprecated. Use canvas.grid.getCenterPoint instead."
      */
     getCenter(x: number, y: number): Canvas.PointTuple;
 
     /**
      * @deprecated since v12, will be removed in v14
-     * @remarks `"GridLayer#getSnappedPosition is deprecated. Use canvas.grid.getCenterPoint instead."`
+     * @remarks "GridLayer#getSnappedPosition is deprecated. Use canvas.grid.getCenterPoint instead."
      */
     getSnappedPosition(
       x: number,
       y: number,
+      /**
+       * @defaultValue `1`
+       * @remarks Can't be `null` due to being used directly as a divisor
+       */
       interval?: number,
-      options?: NullishProps<{
-        /**
-         * The token
-         */
-        token: Token;
-      }>,
-    ): { x: number; y: number };
+      /** @remarks Unused */
+      options?: EmptyObject | null,
+    ): PIXI.IPointData;
 
     /**
      * @deprecated since v12, will be removed in v14
      * @remarks `"GridLayer#measureDistance is deprecated. "Use canvas.grid.measurePath instead for non-Euclidean measurements."`
      */
     measureDistance(
-      origin: {
-        x: number;
-        y: number;
-      },
-      target: {
-        x: number;
-        y: number;
-      },
-      // eslint-disable-next-line @typescript-eslint/no-deprecated
-      options?: GridLayer.MeasureDistancesOptions,
+      origin: Canvas.Point,
+      target: Canvas.Point,
+      /** @remarks Unused */
+      options?: EmptyObject | null,
     ): number;
   }
 
   namespace GridLayer {
+    interface Any extends AnyGridLayer {}
     type AnyConstructor = typeof AnyGridLayer;
 
     interface DrawOptions extends CanvasLayer.DrawOptions {}
@@ -203,62 +182,85 @@ declare global {
       name: "grid";
     }
 
-    interface HighlightPositionOptions {
-      /**
-       * The x-coordinate of the highlighted position
-       * @remarks Required if `canvas.grid !== CONST.GRID_TYPES.GRIDLESS`
-       */
-      x?: number | undefined | null;
+    /** @internal */
+    type _InitializeMeshOptions = NullishProps<{
+      /** The grid style */
+      style: ConfiguredGridStyles;
+    }>;
 
-      /**
-       * The y-coordinate of the highlighted position
-       * @remarks Required if `canvas.grid !== CONST.GRID_TYPES.GRIDLESS`
-       */
-      y?: number | undefined | null;
+    interface InitializeMeshOptions
+      extends _InitializeMeshOptions,
+        Pick<GridMesh.InitializationMeshData, "thickness" | "color" | "alpha"> {}
 
+    /** @internal */
+    type _HighlightPositionOptions = NullishProps<{
       /**
-       * The fill color of the highlight
        * @defaultValue `0x33BBFF`
-       * @privateRemarks `null` is a problem because it's forwarded to a PIXI.Graphics#beginFill call which has a default value set
+       * @remarks This value eventually ends up at `PIXI.Graphics#normalizeColor()`, which handles `null` as `0` (black)
        */
-      color?: PIXI.ColorSource | undefined;
+      color: PIXI.ColorSource | Color;
 
       /**
        * The border color of the highlight
        * @defaultValue `null`
+       * @remarks If `null`, no border will be drawn.
        */
-      border?: PIXI.ColorSource | undefined | null;
+      border: PIXI.ColorSource | Color;
 
       /**
        * The opacity of the highlight
        * @defaultValue `0.25`
+       * @remarks The above is only a parameter default; `PIXI.Graphics#normalizeColor()` will replace `null` with `1`
        */
-      alpha?: number | undefined;
+      alpha: number;
 
       /**
        * A predefined shape to highlight
        * @defaultValue `null`
+       * @remarks Must be provided on gridless scenes or highlighting will fail quietly
        */
-      shape?: PIXI.Polygon | undefined | null;
-    }
+      shape: PIXI.IShape;
+    }>;
 
-    /**
-     * @deprecated since v12, will be removed in v14
-     * @remarks Used by {@link foundry.grid.BaseGrid#measureDistances}
-     */
-    interface Segment {
-      ray: Ray;
-      label?: Ruler["labels"]["children"][number];
+    interface HighlightPositionOptions extends _HighlightPositionOptions {
+      /**
+       * The x-coordinate of the highlighted position
+       * @remarks Required despite Foundry marking it optional. If omitted on gridless will produce `NaN`s,
+       * and on other grid types will insert garbage data into the associated `GridHighlightLayer`
+       */
+      x: number;
+
+      /**
+       * The y-coordinate of the highlighted position
+       * @remarks Required despite Foundry marking it optional. If omitted on gridless will produce `NaN`s,
+       * and on other grid types will insert garbage data into the associated `GridHighlightLayer`
+       */
+      y: number;
     }
 
-    /**
-     * @deprecated since v12, will be removed in v14
-     * @remarks Used by {@link foundry.grid.BaseGrid#measureDistances}
-     */
-    type MeasureDistancesOptions = NullishProps<{
-      /** Return the distance in grid increments rather than the co-ordinate distance. */
-      gridSpaces?: boolean;
+    /** @internal */
+    type _GridStyle = NullishProps<{
+      /** @defaultValue `GridShader` */
+      shaderClass: GridShader.AnyConstructor;
+
+      /** @defaultValue `{}` */
+      shaderOptions: NullishProps<{
+        /**
+         * @defaultValue `0`
+         * @remarks Gets applied to the constructed shaderClass instance's `uniforms`.
+         *
+         * @privateRemarks It's unclear if this is actually repesenting an enum value or not, so it's been left as `number`.
+         */
+        style: number;
+      }>;
     }>;
+
+    interface GridStyle extends _GridStyle {
+      /** @remarks A localization key to display in the Configure Scene sheet */
+      label: string;
+    }
+
+    type ConfiguredGridStyles = keyof RemoveIndexSignatures<CONFIG["Canvas"]["gridStyles"]>;
   }
 }
 
diff --git a/src/foundry/client/pixi/layers/grid/mesh.d.mts b/src/foundry/client/pixi/layers/grid/mesh.d.mts
index 33870867f..79f8c624c 100644
--- a/src/foundry/client/pixi/layers/grid/mesh.d.mts
+++ b/src/foundry/client/pixi/layers/grid/mesh.d.mts
@@ -26,48 +26,69 @@ declare global {
      * }
      * ```
      */
-    data: GridMesh.Data;
+    data: GridMesh.MeshData;
 
     /**
      * Initialize and update the mesh given the (partial) data.
      * @param data - The (partial) data
-     * @remarks InexactPartial is more correct as null has different behavior in _initialize
      */
-    initialize(data: InexactPartial<GridMesh.Data>): this;
+    initialize(data: GridMesh.InitializationMeshData): this;
 
     /**
      * Initialize the data of this mesh given the (partial) data.
      * @param data - The (partial) data.
-     * @remarks Can't be NullishProps because of `!== undefined` tests
      */
-    protected _initialize(data: InexactPartial<GridMesh.Data>): void;
+    protected _initialize(data: GridMesh.InitializationMeshData): void;
   }
 
   namespace GridMesh {
     /**
      * The grid mesh data.
      */
-    interface Data {
-      /** The type of the grid (see {@link CONST.GRID_TYPES}) */
-      type: number;
+    interface MeshData {
+      /**
+       * The type of the grid (see {@link CONST.GRID_TYPES})
+       * @defaultValue `CONST.GRID_TYPES.GRIDLESS`
+       */
+      type: foundry.CONST.GRID_TYPES;
 
-      /** The width of the grid in pixels */
+      /**
+       * The width of the grid in pixels
+       * @defaultValue `0`
+       */
       width: number;
 
-      /** The height of the grid in pixels */
+      /**
+       * The height of the grid in pixels
+       * @defaultValue `0`
+       */
       height: number;
 
-      /** The size of a grid space in pixels */
+      /**
+       * The size of a grid space in pixels
+       * @defaultValue `0`
+       */
       size: number;
 
-      /** The thickness of the grid lines in pixels */
+      /**
+       * The thickness of the grid lines in pixels
+       * @defaultValue `1`
+       */
       thickness: number;
 
-      /** The color of the grid */
+      /**
+       * The color of the grid
+       * @defaultValue `0`
+       */
       color: number;
 
-      /** The alpha of the grid */
+      /**
+       * The alpha of the grid
+       * @defaultValue `1`
+       */
       alpha: number;
     }
+
+    interface InitializationMeshData extends InexactPartial<MeshData> {}
   }
 }
diff --git a/src/foundry/common/grid/base.d.mts b/src/foundry/common/grid/base.d.mts
index 1089ed435..560515b02 100644
--- a/src/foundry/common/grid/base.d.mts
+++ b/src/foundry/common/grid/base.d.mts
@@ -1,4 +1,4 @@
-import type { AnyObject, InexactPartial } from "fvtt-types/utils";
+import type { AnyObject, EmptyObject, InexactPartial } from "fvtt-types/utils";
 
 /**
  * The base grid class.
@@ -366,8 +366,14 @@ declare abstract class BaseGrid {
    * @returns An Array of distance measurements for each segment
    * @deprecated Since v12 until v14. Use {@link BaseGrid#measurePath} instead.
    */
-  // eslint-disable-next-line @typescript-eslint/no-deprecated
-  measureDistances(segments: GridLayer.Segment[], options?: GridLayer.MeasureDistancesOptions): number[];
+  measureDistances(
+    // eslint-disable-next-line @typescript-eslint/no-deprecated
+    segments: BaseGrid.Segment[],
+    /**
+     * @defaultValue `{}`
+     * @remarks Unused */
+    options?: EmptyObject,
+  ): number[];
 
   /* -------------------------------------------- */
 
@@ -390,11 +396,12 @@ declare abstract class BaseGrid {
     x: number,
     y: number,
     interval?: number | null,
-    options?: InexactPartial<{
-      /** The token that is being moved. */
-      token: Token;
-    }>,
-  ): { x: number; y: number };
+    /**
+     * @defaultValue `{}`
+     * @remarks Unused
+     */
+    options?: EmptyObject,
+  ): PIXI.IPointData;
 
   /* -------------------------------------------- */
 
@@ -485,6 +492,9 @@ declare abstract class BaseGrid {
 }
 
 declare namespace BaseGrid {
+  interface Any extends AnyBaseGrid {}
+  type AnyConstructor = typeof AnyBaseGrid;
+
   interface Configuration {
     /** The size of a grid space in pixels (a positive number) */
     size: number;
@@ -631,6 +641,17 @@ declare namespace BaseGrid {
     rows: number;
     columns: number;
   }
+
+  /**
+   * @deprecated since v12, will be removed in v14
+   */
+  interface Segment {
+    ray: Ray;
+  }
+}
+
+declare abstract class AnyBaseGrid extends BaseGrid {
+  constructor(arg0: never, ...args: never[]);
 }
 
 export default BaseGrid;


Test patch:
diff --git a/tests/foundry/client/pixi/layers/grid/highlight.test-d.ts b/tests/foundry/client/pixi/layers/grid/highlight.test-d.ts
index ce2e7f6a3..27581b4e0 100644
--- a/tests/foundry/client/pixi/layers/grid/highlight.test-d.ts
+++ b/tests/foundry/client/pixi/layers/grid/highlight.test-d.ts
@@ -2,9 +2,10 @@ import { expectTypeOf } from "vitest";
 
 expectTypeOf(new GridHighlight("")).toEqualTypeOf<GridHighlight>();
 
-const grid = new GridHighlight("");
+const grid = new GridHighlight("someName");
+
 expectTypeOf(grid.name).toEqualTypeOf<string>();
-expectTypeOf(grid.positions).toEqualTypeOf<Set<string>>();
+expectTypeOf(grid.positions).toEqualTypeOf<Set<GridHighlight.PositionString>>();
 expectTypeOf(grid.highlight(100, 100)).toEqualTypeOf<boolean>();
 expectTypeOf(grid.clear()).toEqualTypeOf<GridHighlight>();
 expectTypeOf(grid.destroy()).toEqualTypeOf<void>();
diff --git a/tests/foundry/client/pixi/layers/grid/layer.test-d.ts b/tests/foundry/client/pixi/layers/grid/layer.test-d.ts
index dba3b5028..50ce516f2 100644
--- a/tests/foundry/client/pixi/layers/grid/layer.test-d.ts
+++ b/tests/foundry/client/pixi/layers/grid/layer.test-d.ts
@@ -1,57 +1,83 @@
 import { expectTypeOf } from "vitest";
-import BaseGrid = foundry.documents.BaseGrid;
+import type BaseGrid from "../../../../../../src/foundry/common/grid/base.d.mts";
+
+// This is deliberately typed incorrectly in v12; runtime would actually return a BaseGrid subtype
+expectTypeOf(GridLayer.instance).toEqualTypeOf<GridLayer>();
 
-expectTypeOf(GridLayer.instance).toEqualTypeOf<GridLayer | undefined>();
 expectTypeOf(GridLayer.layerOptions).toEqualTypeOf<GridLayer.LayerOptions>();
 expectTypeOf(GridLayer.layerOptions.name).toEqualTypeOf<"grid">();
 
 const layer = new GridLayer();
-expectTypeOf(layer.options.name).toEqualTypeOf<"grid">();
-expectTypeOf(layer.grid).toEqualTypeOf<BaseGrid | undefined>();
+
+expectTypeOf(layer.mesh).toEqualTypeOf<GridMesh | undefined>();
 expectTypeOf(layer.highlight).toEqualTypeOf<PIXI.Container | undefined>();
 expectTypeOf(layer.highlightLayers).toEqualTypeOf<Record<string, GridHighlight>>();
-expectTypeOf(layer.type).toEqualTypeOf<foundry.CONST.GRID_TYPES>();
-expectTypeOf(layer.size).toEqualTypeOf<number>();
-expectTypeOf(layer.w).toEqualTypeOf<number>();
-expectTypeOf(layer.h).toEqualTypeOf<number>();
-expectTypeOf(layer.isHex).toEqualTypeOf<boolean>();
+
+expectTypeOf(layer.options.name).toEqualTypeOf<"grid">();
+
 expectTypeOf(layer.draw()).toEqualTypeOf<Promise<GridLayer>>();
 expectTypeOf(layer.draw({})).toEqualTypeOf<Promise<GridLayer>>();
-expectTypeOf(layer.draw({ type: null, dimensions: null, gridColor: null, gridAlpha: null })).toEqualTypeOf<
-  Promise<GridLayer>
->();
-expectTypeOf(layer.draw({ type: foundry.CONST.GRID_TYPES.GRIDLESS })).toEqualTypeOf<Promise<GridLayer>>();
-expectTypeOf(layer.draw({ dimensions: canvas!.dimensions })).toEqualTypeOf<Promise<GridLayer>>();
-expectTypeOf(layer.draw({ gridColor: "#000000" })).toEqualTypeOf<Promise<GridLayer>>();
-expectTypeOf(layer.draw({ gridColor: 0x000000 })).toEqualTypeOf<Promise<GridLayer>>();
-expectTypeOf(layer.draw({ gridAlpha: 0.2 })).toEqualTypeOf<Promise<GridLayer>>();
-expectTypeOf(layer.getSnappedPosition(10, 100)).toEqualTypeOf<{ x: number; y: number }>();
-expectTypeOf(layer.getSnappedPosition(10, 100, 2)).toEqualTypeOf<{ x: number; y: number }>();
-expectTypeOf(layer.getTopLeft(8, 17)).toEqualTypeOf<[number, number]>();
-expectTypeOf(layer.getCenter(8, 17)).toEqualTypeOf<[number, number]>();
-expectTypeOf(layer.measureDistance({ x: 8, y: 17 }, { x: 1100, y: 1200 })).toEqualTypeOf<number>();
-expectTypeOf(layer.measureDistances([{ ray: new Ray({ x: 8, y: 17 }, { x: 1100, y: 1200 }) }])).toEqualTypeOf<
-  number[]
->();
-expectTypeOf(layer.measureDistances([{ ray: new Ray({ x: 8, y: 17 }, { x: 1100, y: 1200 }) }], {})).toEqualTypeOf<
-  number[]
->();
+expectTypeOf(layer["_draw"]({})).toEqualTypeOf<Promise<void>>();
+
+expectTypeOf(layer["_drawMesh"]()).toEqualTypeOf<GridMesh>();
+//@ts-expect-error `initializeMesh` lacks a default for its one parameter, despite all its properties being optional
+expectTypeOf(layer.initializeMesh()).toBeVoid();
+expectTypeOf(layer.initializeMesh({})).toBeVoid();
+expectTypeOf(
+  layer.initializeMesh({
+    alpha: 0.8,
+    color: Color.from(0xabcdef).valueOf(),
+    style: "roundPoints",
+    thickness: 3,
+  }),
+).toBeVoid();
 expectTypeOf(
-  layer.measureDistances([{ ray: new Ray({ x: 8, y: 17 }, { x: 1100, y: 1200 }) }], { gridSpaces: true }),
-).toEqualTypeOf<number[]>();
+  layer.initializeMesh({
+    alpha: undefined,
+    color: undefined,
+    style: null,
+    thickness: undefined,
+  }),
+).toBeVoid();
+
 expectTypeOf(layer.addHighlightLayer("some")).toEqualTypeOf<GridHighlight>();
 expectTypeOf(layer.getHighlightLayer("some")).toEqualTypeOf<GridHighlight | undefined>();
 expectTypeOf(layer.clearHighlightLayer("some")).toEqualTypeOf<void>();
 expectTypeOf(layer.destroyHighlightLayer("some")).toEqualTypeOf<void>();
-expectTypeOf(layer.highlightPosition("some")).toEqualTypeOf<void | false>();
+
+//@ts-expect-error `highlightPosition` requires `x` and `y` properties in its options
+expectTypeOf(layer.highlightPosition("some", {}));
+expectTypeOf(layer.highlightPosition("some", { x: 50, y: 50 })).toEqualTypeOf<void>();
 expectTypeOf(
   layer.highlightPosition("some", {
     x: 10,
     y: 100,
     color: 0x33bbff,
-    border: null,
+    border: Color.from("#ABCFED"),
     alpha: 0.25,
     shape: new PIXI.Polygon(),
   }),
-).toEqualTypeOf<void | false>();
+).toEqualTypeOf<void>();
+expectTypeOf(
+  layer.highlightPosition("some", {
+    x: 10,
+    y: 100,
+    color: null,
+    border: undefined,
+    alpha: undefined,
+    shape: undefined, // will fail silently on gridless
+  }),
+).toEqualTypeOf<void>();
+
+//deprecated since v12 until v14
+expectTypeOf(layer.type).toEqualTypeOf<foundry.CONST.GRID_TYPES>();
+expectTypeOf(layer.size).toEqualTypeOf<number>();
+expectTypeOf(layer.grid).toEqualTypeOf<BaseGrid | null>();
 expectTypeOf(layer.isNeighbor(0, 1, 2, 3)).toEqualTypeOf<boolean>();
+expectTypeOf(layer.w).toEqualTypeOf<number>();
+expectTypeOf(layer.h).toEqualTypeOf<number>();
+expectTypeOf(layer.isHex).toEqualTypeOf<boolean>();
+expectTypeOf(layer.getTopLeft(8, 17)).toEqualTypeOf<[number, number]>();
+expectTypeOf(layer.getCenter(8, 17)).toEqualTypeOf<[number, number]>();
+expectTypeOf(layer.getSnappedPosition(10, 100, 2)).toEqualTypeOf<{ x: number; y: number }>();
+expectTypeOf(layer.measureDistance({ x: 8, y: 17 }, { x: 1100, y: 1200 })).toEqualTypeOf<number>();
diff --git a/tests/foundry/client/pixi/layers/grid/mesh.test-d.ts b/tests/foundry/client/pixi/layers/grid/mesh.test-d.ts
new file mode 100644
index 000000000..3731b0cc9
--- /dev/null
+++ b/tests/foundry/client/pixi/layers/grid/mesh.test-d.ts
@@ -0,0 +1,17 @@
+import { expectTypeOf } from "vitest";
+
+const myGridMesh = new GridMesh(GridShader);
+
+expectTypeOf(myGridMesh.data.type).toMatchTypeOf<CONST.GRID_TYPES>();
+
+const myGridMeshData = {
+  type: CONST.GRID_TYPES.HEXEVENQ,
+  width: 100,
+  height: 100,
+  size: 128,
+  thickness: undefined,
+  alpha: 0.72,
+};
+
+expectTypeOf(myGridMesh.initialize(myGridMeshData)).toEqualTypeOf<typeof myGridMesh>();
+expectTypeOf(myGridMesh["_initialize"](myGridMeshData)).toBeVoid();