Using TypeScript with p5.js

I tried this article’s setup, but it didn’t work for me. But the same author had a project that did work for me with Vite rather than Parcel: https://github.com/bulkan/polylines/

I’m duplicating a version of that here as a reference for myself for future p5.js projects.

Instructions

npm init
npm install --save-dev vite
npm install p5

Folder structure:

index.html
package.json
tsconfig.json
src/
  index.ts
  util.ts

package.json:

{
  ...
  "scripts": {
    "dev": "vite --host 0.0.0.0",
    "build": "tsc --noEmit && vite build",
  }
  ...
}

tsconfig.json:

{
  "include": ["src"]
}

index.html:

<!DOCTYPE html>
<html>
<head>
  <script type="module" src="./src/index.ts"></script>
</head>
<body>
  <div id="p5sketch"></div>
</body>
</html>

src/index.ts:

import p5 from "p5"; 
// Some tools seemed to prefer '.js' while other tools worked fine either way. I
// guess since Vite works fine with './util' or './util.ts' (Parcel didn't for me),
// maybe one of those is more idiomatic.
import { foo } from "./util.js";

const sketch = (p: p5) => {
  let x = 0;
  let y = 0;

  p.setup = () => {
    p.createCanvas(200, 200);
  };

  p.draw = () => {
    p.background(0);
    p.rect(x, y, 50, 50);

    x += 1;
    y += 1;

    if (x >= 200) {
      x = 0;
    }
    if (y >= 200) {
      y = 0;
    }
  };
};

new p5(sketch, document.getElementById("p5sketch")!);

src/util.ts (just an example of doing module imports):

export function foo(x: number, y: number): number {
  return x + y;
}